Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^3: How come @_ gets changed here?

by dave_the_m (Prior)
on Jun 10, 2017 at 18:07 UTC ( #1192481=note: print w/replies, xml ) Need Help??


in reply to Re^2: How come @_ gets changed here?
in thread How come @_ gets changed here?

It's not particularly a regression. Perl suffers from a particular over-arching bug, which is hard to fix (which is why it hasn't been fixed yet): elements on perl's execution stack are not reference counted. This means that if you empty something like an array whose elements are on the stack (and will have been aliased to elements of @_ if this is a function call), and if nothing else holds a reference count to those elements, then they will be prematurely freed (and possibly re-allocated) while still accessible.

That commit merely causes that bug to show up where previously it happened to be masked. For example in 5.22.0 with this code:

my @a=(3,4); sub x { @a = (); print "[$_]" for @_; print "\n"; } x(@a);
you get:
$ perl5220 -w ~/tmp/p Use of uninitialized value $_ in concatenation (.) or string at /home/ +davem/tmp/p line 9. Use of uninitialized value $_ in concatenation (.) or string at /home/ +davem/tmp/p line 9. [][]

Dave.

Replies are listed 'Best First'.
Re^4: How come @_ gets changed here?
by haukex (Abbot) on Jun 11, 2017 at 13:09 UTC

    Thanks for the info! I remember seeing references to the "the stack isn't refcounted bug" from my casual lurking on P5P - I just checked again and recent references appear to be Stack refcount synopsis and perl #114372. If it's unclear when it'll be fixed, maybe it would make sense to include a blurb about the nature of the bug in the documentation, something like what you wrote here in this thread?

Re^4: How come @_ gets changed here?
by Anonymous Monk on Jun 10, 2017 at 18:56 UTC
    So what's the take-away here? If your sub has to put stuff in variables outside its own scope, don't also pass those variables as parameters?
      the rough rule is: don't free elements of arrays and hashes (e.g. by assigning a list to the array or hash) when those elements are currently the arguments of a funtion call, or are being iterated over by for(), etc.

      Dave.

        Please correct me if I'm wrong, but as long as I copy the args in my first line, it should be safe from messed up ref counts, shouldn't it?

        my ($a, $b) = @_

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

      > So what's the take-away here? If your sub has to put stuff in variables outside its own scope, don't also pass those variables as parameters?

      It's even more complicated.

      You could call another sub (which calls another sub) which is deleting elements from the closure before accessing @_.

      I think the rule of thumb is

      • always try to copy @_ first and avoid accessing any $_[n] afterwards.
      • if you really need the aliasing effect or high performance, be sure to avoid side effects by calling unknown functions or even directly overwriting closed over vars.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Je suis Charlie!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1192481]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2018-06-19 21:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?



    Results (115 votes). Check out past polls.

    Notices?