Mailing List Archive

__ANON__ patch
As you may know, currently perl cannot debug in the presence of
anonymous closures, trying to autoload a subroutine __ANON__ from the
package where the closure was defined.

The patch below is not definitive, it is just cosmetic: it avoids the
problem using some redundancy of the data. The real reason for the
problem is that anonymous closures somehow miss the SVpcv_ANON flag.

To demonstrate it I will use the updated specially for this occasion
Peek module (as usual, available on
ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl, changes with
respect to the previous version are 1) recursive dumping of hashes,
and 2) a lot of additional info about CV):

monk:~->perld -e 'use ExtUtils::Peek "Dump"; my $a; Dump sub {}'
SV = RV(0x16fc0c)
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x127a48
SV = PVCV(0x120908)
REFCNT = 2
FLAGS = (ANON)
IV = 0
NV = 0
STASH = main
START = 0x12efc8
ROOT = 0x12ecc8
XSUB = 0x0
XSUBANY = 0
GV = 0x1279d0 "__ANON__"
FILEGV = 0x11fd1c
DEPTH = 0
PADLIST = 0x1279dc


monk:~->perld -e 'use ExtUtils::Peek "Dump"; my $a; Dump sub {$a}'
SV = RV(0x16fc0c)
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x11fc38
SV = PVCV(0x120988)
REFCNT = 2
FLAGS = (CLONE,CLONED)
IV = 0
NV = 0
STASH = main
START = 0x12edc8
ROOT = 0x12ed08
XSUB = 0x0
XSUBANY = 0
GV = 0x1279f4 "__ANON__"
FILEGV = 0x11fd1c
DEPTH = 0
PADLIST = 0x135038

As you see, the closure has flags CLONE and CLONED, but misses the
flag ANON. The patch below just looks on additional info: name-of-GV
to see that the closure is actually anonymous. Sorry, I'm too lazy to
look for actual reason for perl (mis)behaviour.

The patch is active during debugging only, so should not substantially
slow down execution. Here it is:

*** pp_hot.c~ Thu Jun 22 07:28:06 1995
--- pp_hot.c Wed Sep 13 00:02:30 1995
***************
*** 1622,1628 ****
if ((op->op_private & OPpDEREF_DB) && !CvXSUB(cv)) {
sv = GvSV(DBsub);
save_item(sv);
! if (SvFLAGS(cv) & SVpcv_ANON) /* Is GV potentially non-unique? */
sv_setsv(sv, newRV((SV*)cv));
else {
gv = CvGV(cv);
--- 1622,1629 ----
if ((op->op_private & OPpDEREF_DB) && !CvXSUB(cv)) {
sv = GvSV(DBsub);
save_item(sv);
! if (SvFLAGS(cv) & SVpcv_ANON ||
! strcmp(GvNAME(CvGV(cv)),"__ANON__") == 0) /* Is GV potentially non-unique? */
sv_setsv(sv, newRV((SV*)cv));
else {
gv = CvGV(cv);


Enjoy,
Ilya
Re: __ANON__ patch [ In reply to ]
On Wed, 13 Sep 1995 04:10:28 EDT, Ilya Zakharevich wrote:
>As you may know, currently perl cannot debug in the presence of
>anonymous closures, trying to autoload a subroutine __ANON__ from the
>package where the closure was defined.
>
>The patch below is not definitive, it is just cosmetic: it avoids the
>problem using some redundancy of the data. The real reason for the
>problem is that anonymous closures somehow miss the SVpcv_ANON flag.
>

I thought I posted a patch for this (very similar to yours below) about
a month back both here and on the pTk mailing list.. Did you miss that one?
It's also a part of the consolidated patchset on mox.perl.com. I have
been happily debugging Tk apps and closures ever since :-)

>As you see, the closure has flags CLONE and CLONED, but misses the
>flag ANON. The patch below just looks on additional info: name-of-GV
>to see that the closure is actually anonymous. Sorry, I'm too lazy to
>look for actual reason for perl (mis)behaviour.
>

I think CLONE subsumes ANON, so you can actually just do:

if (SvFLAGS(cv) & (SVpcv_ANON | SVpcv_CLONE))

instead, and get away with it.

>
>*** pp_hot.c~ Thu Jun 22 07:28:06 1995
>--- pp_hot.c Wed Sep 13 00:02:30 1995
>***************
>*** 1622,1628 ****
> if ((op->op_private & OPpDEREF_DB) && !CvXSUB(cv)) {
> sv = GvSV(DBsub);
> save_item(sv);
>! if (SvFLAGS(cv) & SVpcv_ANON) /* Is GV potentially non-unique? */
> sv_setsv(sv, newRV((SV*)cv));
> else {
> gv = CvGV(cv);
>--- 1622,1629 ----
> if ((op->op_private & OPpDEREF_DB) && !CvXSUB(cv)) {
> sv = GvSV(DBsub);
> save_item(sv);
>! if (SvFLAGS(cv) & SVpcv_ANON ||
>! strcmp(GvNAME(CvGV(cv)),"__ANON__") == 0) /* Is GV potentially non-unique? */
> sv_setsv(sv, newRV((SV*)cv));
> else {
> gv = CvGV(cv);
>
>
>Enjoy,
>Ilya
>

- Sarathy.
gsar@engin.umich.edu
Re: __ANON__ patch [ In reply to ]
Gurusamy Sarathy writes:
> I thought I posted a patch for this (very similar to yours below) about
> a month back both here and on the pTk mailing list.. Did you miss that one?
> It's also a part of the consolidated patchset on mox.perl.com. I have
> been happily debugging Tk apps and closures ever since :-)
>

Pity, I got consolidated patch from my p5-p archive, and this was not
there.

> >As you see, the closure has flags CLONE and CLONED, but misses the
> >flag ANON. The patch below just looks on additional info: name-of-GV
> >to see that the closure is actually anonymous. Sorry, I'm too lazy to
> >look for actual reason for perl (mis)behaviour.
> >
>
> I think CLONE subsumes ANON, so you can actually just do:
>
> if (SvFLAGS(cv) & (SVpcv_ANON | SVpcv_CLONE))
>
> instead, and get away with it.
>

Definitely no, check your patch against this. I do not know why
anonymous closure is CLONED though:

monk:~->perld -e 'use ExtUtils::Peek "Dump"; my $a; sub a {$a}; Dump \&a'
SV = RV(0x16fc0c)
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x127a48
SV = PVCV(0x120908)
REFCNT = 2
FLAGS = (CLONE)
IV = 0
NV = 0
STASH = main
START = 0x12edc8
ROOT = 0x12ed08
XSUB = 0x0
XSUBANY = 0
GV = 0x1279f4 "a"
FILEGV = 0x11fd1c
DEPTH = 0
PADLIST = 0x1279dc

Ilya
Re: __ANON__ patch [ In reply to ]
On Wed, 13 Sep 1995 17:06:48 EDT, Ilya Zakharevich wrote:
>Gurusamy Sarathy writes:
>> I think CLONE subsumes ANON, so you can actually just do:
>>
>> if (SvFLAGS(cv) & (SVpcv_ANON | SVpcv_CLONE))
>>
>> instead, and get away with it.
>>
>
>Definitely no, check your patch against this. I do not know why
>anonymous closure is CLONED though:
>
>monk:~->perld -e 'use ExtUtils::Peek "Dump"; my $a; sub a {$a}; Dump \&a'
>SV = RV(0x16fc0c)
> REFCNT = 1
> FLAGS = (TEMP,ROK)
> RV = 0x127a48
>SV = PVCV(0x120908)
> REFCNT = 2
> FLAGS = (CLONE)
> IV = 0
> NV = 0
> STASH = main
> START = 0x12edc8
> ROOT = 0x12ed08
> XSUB = 0x0
> XSUBANY = 0
> GV = 0x1279f4 "a"
> FILEGV = 0x11fd1c
> DEPTH = 0
> PADLIST = 0x1279dc

Huh-oh, that's not true on my perl. Here's my output:

[ 52 ] Peek> perl -I./blib -e 'use ExtUtils::Peek "Dump"; my $a; sub a {$a}; Dump \&a'
SV = RV(0x12d00c)
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0xeaea8
SV = PVCV(0xe5e08)
REFCNT = 2
FLAGS = ()
IV = 0
NV = 0
STASH = 0xc9044
START = 0xf3888
ROOT = 0xf2fc8
XSUB = 0x0
XSUBANY = 0
FILEGV = 0xc9134
DEPTH = 0
PADLIST = 0xeae3c

Can somebody else please verify this also?

>
>Ilya
>

- Sarathy.
gsar@engin.umich.edu
Re: __ANON__ patch [ In reply to ]
On Wed, 13 Sep 1995 17:23:52 EDT, I deluded:
>On Wed, 13 Sep 1995 17:06:48 EDT, Ilya Zakharevich wrote:
>>Gurusamy Sarathy writes:
>>> I think CLONE subsumes ANON, so you can actually just do:
>>>
>>> if (SvFLAGS(cv) & (SVpcv_ANON | SVpcv_CLONE))
>>>
>>> instead, and get away with it.
>>>
>>
>>Definitely no, check your patch against this. I do not know why
>>anonymous closure is CLONED though:
>>
>>monk:~->perld -e 'use ExtUtils::Peek "Dump"; my $a; sub a {$a}; Dump \&a'
>>SV = RV(0x16fc0c)
>> REFCNT = 1
>> FLAGS = (TEMP,ROK)
>> RV = 0x127a48
>>SV = PVCV(0x120908)
>> REFCNT = 2
>> FLAGS = (CLONE)
>> IV = 0
>> NV = 0
>> STASH = main
>> START = 0x12edc8
>> ROOT = 0x12ed08
>> XSUB = 0x0
>> XSUBANY = 0
>> GV = 0x1279f4 "a"
>> FILEGV = 0x11fd1c
>> DEPTH = 0
>> PADLIST = 0x1279dc
>
>Huh-oh, that's not true on my perl. Here's my output:
>
> [ 52 ] Peek> perl -I./blib -e 'use ExtUtils::Peek "Dump"; my $a; sub a {$a}; Dump \&
>a'
> SV = RV(0x12d00c)
> REFCNT = 1
> FLAGS = (TEMP,ROK)
> RV = 0xeaea8
> SV = PVCV(0xe5e08)
> REFCNT = 2
> FLAGS = ()
> IV = 0
> NV = 0
> STASH = 0xc9044
> START = 0xf3888
> ROOT = 0xf2fc8
> XSUB = 0x0
> XSUBANY = 0
> FILEGV = 0xc9134
> DEPTH = 0
> PADLIST = 0xeae3c
>
>Can somebody else please verify this also?
>

False alarm, sorry. It turns out that I had an older version of Peek that
does not dump CLONE/CLONED/ANON. The output does match yours as originally
posted. This means that

sv.h:134:#define SVpcv_CLONE 0x80000000 /* anon CV uses external lexicals */

sports an incorrect comment (or that the comment is right and its a bug :)

My patch also works, but will report the wrong names for subs in the
debugger:

main::CODE(0xe4f68)(-:1): my $a; sub a { print $a } $a = 'xxx'; a();
^^^^^^^^^^^^^ <--- stringified ref to sub instead of name with my patch

SVpcv_CLONED seems to be set only on closures though (with all my little
examples), and using that _may_ be a reliable way to find if it is a closure.


- Sarathy.
gsar@engin.umich.edu
Re: __ANON__ patch [ In reply to ]
: False alarm, sorry. It turns out that I had an older version of Peek that
: does not dump CLONE/CLONED/ANON. The output does match yours as originally
: posted. This means that
:
: sv.h:134:#define SVpcv_CLONE 0x80000000 /* anon CV uses external lexicals */
:
: sports an incorrect comment (or that the comment is right and its a bug :)

The comment is a bit misleading. The CLONE flag is set in any
subroutine that references external lexicals. Indeed, the grammar
reduction for the subroutine definition hasn't happened yet, so it
could only be known withing pad_findlex() by examining that the current
subname to see if it is "__ANON__". And that's not worth the bother,
since the CLONE flag is only examined by pp_anoncode(), which is only
called if the anonymous subroutine reduction happens.

: My patch also works, but will report the wrong names for subs in the
: debugger:
:
: main::CODE(0xe4f68)(-:1): my $a; sub a { print $a } $a = 'xxx'; a();
: ^^^^^^^^^^^^^ <--- stringified ref to sub instead of name with my patch
:
: SVpcv_CLONED seems to be set only on closures though (with all my little
: examples), and using that _may_ be a reliable way to find if it is a closure.

I believe so. The only way to get a live reference to a closure is by
calling cv_clone, and that sets CLONED. Note that people are often
confused as to whether they're really writing a closure or just an
anonymous subroutine. It all depends on whether there are references
to external lexicals or not.

Larry
Re: __ANON__ patch [ In reply to ]
Gurusamy Sarathy writes:
> SVpcv_CLONED seems to be set only on closures though (with all my little
> examples), and using that _may_ be a reliable way to find if it is a closure.

I'm currently making use of cv_clone in multi-threaded perl so that
when two threads enter an unsynchronised sub at the same time they
each get separate pads. There may be a better way of doing this and it
may not be relevant to what you're doing but I thought I'd mention it.

--Malcolm

--
Malcolm Beattie <mbeattie@sable.ox.ac.uk>
Unix Systems Programmer
Oxford University Computing Services