On Mon, 27 Feb 2023 at 13:17, demerphq <demerphq@gmail.com> wrote: > Because the scalar that holds "foo" has been pushed onto the stack > independently of the array that originally contains it. The fact that > perl aliases arguments is a key part of this bug. If the stack was > refcounted the alias would not be freed until the scalar was popped from > the stack. > With the alias comment what i mean is that if we passed arguments by value and not by reference, then the refcount of all arguments on the stack would be 1, and we wouldn't need to refcount the stack. But we pass aliases because we expect this to output "bar": ./perl -MDevel::Peek -le'my @a=("foo"); sub t { $_[1]= "bar"; } t(\@a,$a[0]); print "@a"' bar Another example of this is visible with Carp::confess: With daves fix: $ ./perl -MDevel::Peek -MCarp=confess -le'my @a=("foo"); sub t {@{$_[0]}=(); t2(@_); } sub t2 { confess("in t2"); } Dump($a[0]); t(\@a,$a[0]);' SV = PV(0x5612751a6f68) at 0x5612751a6570 REFCNT = 2 FLAGS = (POK,IsCOW,pPOK) PV = 0x5612752d7bb8 "foo"\0 CUR = 3 LEN = 16 COW_REFCNT = 1 in t2 at -e line 1. main::t2(ARRAY(0x5612751d8778), "foo") called at -e line 1 main::t(ARRAY(0x5612751d8778), "foo") called at -e line 1 Without: $ perl -MDevel::Peek -MCarp=confess -le'my @a=("foo"); sub t {@{$_[0]}=(); t2(@_); } sub t2 { confess("in t2"); } Dump($a[0]); t(\@a,$a[0]);' SV = PV(0x561591981f68) at 0x561591981570 REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x561591ab4568 "foo"\0 CUR = 3 LEN = 16 COW_REFCNT = 1 in t2 at -e line 1. main::t2(ARRAY(0x5615919b3788), "") called at -e line 1 main::t(ARRAY(0x5615919b3788), "") called at -e line 1 The behavior of the latter case is actually somewhat modern, in older perls Carp::confess used to segfault from this issue. cheers, Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"Thread Previous | Thread Next