List Info

Thread: Re: Warning and segfault when using use constant and use sub




Re: Warning and segfault when using use constant and use sub
user name
2007-09-24 06:31:01
On Fri, Sep 21, 2007 at 12:25:44PM +0100, Nicholas Clark
wrote:
> On Thu, Sep 20, 2007 at 03:22:47PM -0700, srezic  cpan.
org wrote:
> > # New Ticket Created by  sreziccpan.org

> > # Please include the string:  [perl #45607]
> > # in the subject line of all future correspondence
about this issue. 
> > # <URL: h
ttp://rt.perl.org/rt3/Ticket/Display.html?id=45607 >
> > 
> > 
> > This is a bug report for perl from sreziccpan.org,
> > generated with the help of perlbug 1.36 running
under perl 5.10.0.
> > 
> > 
> >
------------------------------------------------------------
-----
> > The following script generates a new warning in
perl5.10.0, but not
> > in perl5.8.8:
> > 
> >      Constant subroutine main::BLA redefined at
/usr/perl5.10.0d/lib/5.10.0/subs.pm line 36.
> > 
> > Also, on exit there is a core dump
> > 
> > #!perl
> > use constant BLA => "foo";
> > use subs qw(BLA);
> 
> Mmm, that line probably shouldn't warn:
> 
> sub import {
>     my $callpack = caller;
>     my $pack = shift;
>     my imports = _;
>     foreach $sym (imports) {
>         *{"$::$sym"} =
&{"$::$sym"};
>     }
> };
> 
> but thinking about the implementation, and what happens
when, it might be
> tricky to stop it from warning.

Fixing the bug fixed the warning. (change 31940). It's a
sutle corner case.

For the general case, what happens for *{"GLIPP"}
= &{"BONK"} is that the
peephole optimiser spots that construction, and adds flags
to two of the ops
to make the code lookup return a scalar reference if
possible, and the glob
assignment to assign that reference direct to the symbol
table if possible,
otherwise fix things up as if there had never been any
cheating:

The corner case is when $::BONK is a reference, and you
execute
*{"BONK"} = &{"BONK"}


Step 1:  ops for &{"BONK"}; return us the
constant in the symbol table
Step 2:  ops for *{"BONK"} cause that symbol table
entry (and our reference
         to it) to be upgraded from RV to typeblob)
Step 3:  We got to the code that attempted to assign the
reference into the
         symbol table. A new reference needs to be created
and the referant
         (the constant) pointed to it. (Rather than simply
bumping the
         reference count of the existing reference, making a
new alias to it)
         However, what has happened in step 2 is that the
reference placed on
         the stack by step 1 has been converted to a
typeglob, which the old
         code didn't realise could happen. So it still
merrily called SvRV() on
         it to dereference it, and boom!

So now the code in step 3 is more robust, and handles the
case of the item
on the stack being changed from RV to PVGV.

Nicholas Clark

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )