develooper Front page | perl.perl5.porters | Postings from February 2023

Re: PERL_RC_STACK branch: first cut

Thread Previous | Thread Next
From:
demerphq
Date:
February 27, 2023 12:18
Subject:
Re: PERL_RC_STACK branch: first cut
Message ID:
CANgJU+Xj+eoCTLCvdowpM9PUj5V4gxh4tMt5MMz3+PVKpNpBBQ@mail.gmail.com
On Mon, 27 Feb 2023 at 12:45, Ruud H.G. van Tol via perl5-porters <
perl5-porters@perl.org> wrote:

>
> On 2023-02-27 12:20, demerphq wrote:
> > For those who want a simple example of the bug that this patch fixes
> > here is a simple example:
> >
> > With blead perl this program should print out "foo", but does not.
> > $ perl -le'my @a=("foo"); sub t {@{$_[0]}=(); print $_[1];}
> > t(\@a,$a[0]);'
> >
> > With Dave's branch it behaves as expected:
> > $ ./perl -le'my @a=("foo"); sub t {@{$_[0]}=(); print $_[1];}
> > t(\@a,$a[0]);'
> > foo
> >
>
> To me that is a confusing example.
>

Er, sorry, but I can't help that, that *is* the bug that Dave is fixing
with this PR.

I think have become so habituated to the bug that you dont recognize it as
a bug. :-) But it is still a bug. See below.


> I don't see (yet) how/why it should print out "foo".\
>


> Why would you want/expect it to print "foo",
> when you are using aliased parameters,
> and are deliberately emptying the array?
>

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.

Note I did:

t(\@a, $a[0]);

so the array that contains "foo" has been pushed onto the stack, as has an
element it contained. When the stack is buggily not refcounted clearing the
array ref frees the scalar, so that when you go to print it out it has been
prematurely freed.

Change the example to using Devel::Peek and you can see that something
*weird* has happened. Notice the SV = UNKNOWN(0xff) and notice the
REFCNT=0. What you are seeing there is the result of some of the defensive
logic we have in place to work around the fact that the stack is not
refcounted.  No part of perl should *ever* see an SV with a refcount of 0.
It simply should never happen.

With latest blead:
$ perl -MDevel::Peek -le'my @a=("foo"); sub t {@{$_[0]}=(); Dump($_[1]);}
Dump($a[0]); t(\@a,$a[0]);'
SV = PV(0x55e853845f68) at 0x55e853845570
  REFCNT = 1
  FLAGS = (POK,IsCOW,pPOK)
  PV = 0x55e85384a828 "foo"\0
  CUR = 3
  LEN = 16
  COW_REFCNT = 1
SV = UNKNOWN(0xff) (0x55e853845750) at 0x55e853845570
  REFCNT = 0
  FLAGS = ()

With Dave's branch:
$ ./perl -MDevel::Peek -le'my @a=("foo"); sub t {@{$_[0]}=(); Dump($_[1]);}
Dump($a[0]); t(\@a,$a[0]);'
SV = PV(0x55e86292cf68) at 0x55e86292c570
  REFCNT = 2
  FLAGS = (POK,IsCOW,pPOK)
  PV = 0x55e862931828 "foo"\0
  CUR = 3
  LEN = 16
  COW_REFCNT = 1
SV = PV(0x55e86292cf68) at 0x55e86292c570
  REFCNT = 2
  FLAGS = (POK,IsCOW,pPOK)
  PV = 0x55e862931828 "foo"\0
  CUR = 3
  LEN = 16
  COW_REFCNT = 1
--
perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About