On Tue, Feb 05, 2008 at 11:28:02PM +0000, Nicholas Clark wrote:
> On Tue, Feb 05, 2008 at 11:08:37PM +0000, var Arnfjr Bjarmason wrote:

> > The unpack/potentially rx related segfault mauke reported a while back
> > which I did some initial analysis of still hasn't been solved in 5.8.x
> > or 5.10.x. It would be nice if yourself or someone with more optree
> 
> It wasn't solved in 5.8.8 so it's not a regression.
> 
> > tuits would take a look at it. Maybe it's trivial to fix and if so it
> 
> The optree is not my strong point at all.
> 
> > would be a shame if we shipped a perl with known segfaults, especially
> > as those might always be potential security issues.
> > 
> > $ perl -le 'split //, unpack("(B)*", "ab")'
> > Segmentation fault
> 
> Curiously, the (I believe) functionally equivalent non-grouping version is
> fine:
> 
> $ perl -le 'split //, unpack("B*", "ab")'
> $

No, *this*, "BB", is the functionally equivalent, I think.
And as *it* works it means that it can't be the optree. So, single stepping
in the debugger good:

4676        Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
(gdb)
4680        if (!pm || !s)
(gdb)
4682        rx = PM_GETRE(pm);
(gdb) p pm
$8 = (PMOP *) 0x8c25b0

vs bad:

4676        Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
(gdb)
4680        if (!pm || !s)
(gdb)
4682        rx = PM_GETRE(pm);
(gdb) p pm
$7 = (PMOP *) 0x8


so, it's stacks.

$ ./perl -Ds -le 'split //, unpack("BB", "ab")'

EXECUTING...

    =>
    =>
    =>
    =>  PVLV()
    =>  PVLV()  PV("BB"\0)
    =>  PVLV()  PV("BB"\0)  PV("ab"\0)
    =>  PVLV()  PV("0"\0)
    =>  PVLV()  PV("0"\0)  IV(0)
    =>  IV(1)

$ ./perl -Ds -le 'split //, unpack("(B)*", "ab")'     
EXECUTING...

    =>
    =>
    =>
    =>  PVLV()
    =>  PVLV()  PV("(B)*"\0)
    =>  PVLV()  PV("(B)*"\0)  PV("ab"\0)
    =>  PVLV()  PV("0"\0)  PV("0"\0)
    =>  PVLV()  PV("0"\0)  PV("0"\0)  IV(0)
Segmentation fault



anyone familiar enough with the code or stacks to know why it's leaving too
much on the stack? And why it only happens with split? For example list
assignment (and print, and foreach) are identical for "BB" and "(B)*"
(and why the split // case puts IV(0) on the stack, whereas the others
put a PV of "0")

$ ./perl -Dts -le '@a = unpack("BB", "ab")'

EXECUTING...

    =>  
(-e:0)  enter
    =>  
(-e:0)  nextstate
    =>  
(-e:1)  pushmark
    =>  *  
(-e:1)  const(PV("BB"\0))
    =>  *  PV("BB"\0)  
(-e:1)  const(PV("ab"\0))
    =>  *  PV("BB"\0)  PV("ab"\0)  
(-e:1)  unpack
    =>  *  PV("0"\0)  PV("0"\0)  
(-e:1)  pushmark
    =>  *  PV("0"\0)  PV("0"\0)  *  
(-e:1)  gv(main::a)
    =>  *  PV("0"\0)  PV("0"\0)  *  GV()  
(-e:1)  rv2av
    =>  *  PV("0"\0)  PV("0"\0)  *  AV()  
(-e:1)  aassign
    =>  
(-e:1)  leave
$ ./perl -Dts -le '@a = unpack("(B)*", "ab")'

EXECUTING...

    =>  
(-e:0)  enter
    =>  
(-e:0)  nextstate
    =>  
(-e:1)  pushmark
    =>  *  
(-e:1)  const(PV("(B)*"\0))
    =>  *  PV("(B)*"\0)  
(-e:1)  const(PV("ab"\0))
    =>  *  PV("(B)*"\0)  PV("ab"\0)  
(-e:1)  unpack
    =>  *  PV("0"\0)  PV("0"\0)  
(-e:1)  pushmark
    =>  *  PV("0"\0)  PV("0"\0)  *  
(-e:1)  gv(main::a)
    =>  *  PV("0"\0)  PV("0"\0)  *  GV()  
(-e:1)  rv2av
    =>  *  PV("0"\0)  PV("0"\0)  *  AV()  
(-e:1)  aassign
    =>  
(-e:1)  leave


Nicholas Clark

Reply via email to