Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.16] Unreferenced scalar in recursion #12952

Open
p5pRT opened this issue May 9, 2013 · 6 comments
Open

[5.16] Unreferenced scalar in recursion #12952

p5pRT opened this issue May 9, 2013 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented May 9, 2013

Migrated from rt.perl.org#117929 (status was 'open')

Searchable as RT117929$

@p5pRT
Copy link
Author

p5pRT commented May 9, 2013

From @Grimy

I have some (horrifyingly golfed) code to recursively build a binary search
tree, based on an array containing the depth of the elements (as described
in RFC 1951 <http​://www.ietf.org/rfc/rfc1951.txt>, pp.6–8). It works fine
under Perl 5.8 and 5.14, but it breaks loudly under 5.16, with 15 “Attempt
to free unreferenced scalar” messages.

Here is the simplest version I could come up with that still triggers the
bug​:

sub rec {
$depth++;
return @​_ if $depth == 16;
@​_ = ((grep { $_[$_] == $depth } 0..$#_), &rec);
map { [shift, shift] } @​_
}

rec(1, 1)

@p5pRT
Copy link
Author

p5pRT commented May 9, 2013

From @jkeenan

On Thu May 09 09​:49​:24 2013, victor.adam@​derpymail.org wrote​:

I have some (horrifyingly golfed) code to recursively build a binary
search
tree, based on an array containing the depth of the elements (as described
in RFC 1951 <http​://www.ietf.org/rfc/rfc1951.txt>, pp.6–8). It works fine
under Perl 5.8 and 5.14, but it breaks loudly under 5.16, with 15 “Attempt
to free unreferenced scalar” messages.

Here is the simplest version I could come up with that still triggers the
bug​:

sub rec {
$depth++;
return @​_ if $depth == 16;
@​_ = ((grep { $_[$_] == $depth } 0..$#_), &rec);
map { [shift, shift] } @​_
}

rec(1, 1)

I can confirm that I get this in Perl 5.16.0 but not in 5.14.2. But I
can't understand your program well enough (e.g., why are you assigning
to @​_ ?) to help further.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented May 9, 2013

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented May 10, 2013

From @iabyn

On Thu, May 09, 2013 at 04​:49​:58PM -0700, James E Keenan via RT wrote​:

On Thu May 09 09​:49​:24 2013, victor.adam@​derpymail.org wrote​:

I have some (horrifyingly golfed) code to recursively build a binary
search
tree, based on an array containing the depth of the elements (as described
in RFC 1951 <http​://www.ietf.org/rfc/rfc1951.txt>, pp.6–8). It works fine
under Perl 5.8 and 5.14, but it breaks loudly under 5.16, with 15 “Attempt
to free unreferenced scalar” messages.

Here is the simplest version I could come up with that still triggers the
bug​:

sub rec {
$depth++;
return @​_ if $depth == 16;
@​_ = ((grep { $_[$_] == $depth } 0..$#_), &rec);
map { [shift, shift] } @​_
}

rec(1, 1)

The code can be simplified to​:

  @​a = (1,1,1,1);
  map { [shift @​a, shift @​a] } @​a;

i.e. elements of @​a are being shifted off, copied and then freed, while
the elements of the array are still being iterated over.

It's another example of the perl stack not being reference counted.

--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
  -- Larry Wall

@p5pRT
Copy link
Author

p5pRT commented May 11, 2013

From @Grimy

Hello,

As I said, I originally discovered the bug while golfing. Assigning to @​_
saved a few keystrokes. I just experemented further, and it turns out the
bug can be reproduced without this assignment​:

sub rec {
$depth++;
return @​_ if $depth == 16;
@​tree = ((grep { $_[$_] == $depth } 0..$#_), &rec);
map { [shift @​tree, shift @​tree] } @​tree;
}

rec(1, 1);

Note that the block passed to map completely ignores $_. Since each
iteration consumes 2 elements of @​tree, the sensible thing to do would be
to iterate over 1..@​tree/2 —*way *too many keystrokes. However, the problem
only occurs when iterating over @​tree. I'm aware that this kind of hack is
unlikely to occur in production code.

Thank you,

Victor Adam

2013/5/10 James E Keenan via RT <perlbug-followup@​perl.org>

On Thu May 09 09​:49​:24 2013, victor.adam@​derpymail.org wrote​:

I have some (horrifyingly golfed) code to recursively build a binary
search
tree, based on an array containing the depth of the elements (as
described
in RFC 1951 <http​://www.ietf.org/rfc/rfc1951.txt>, pp.6–8). It works
fine
under Perl 5.8 and 5.14, but it breaks loudly under 5.16, with 15
“Attempt
to free unreferenced scalar” messages.

Here is the simplest version I could come up with that still triggers the
bug​:

sub rec {
$depth++;
return @​_ if $depth == 16;
@​_ = ((grep { $_[$_] == $depth } 0..$#_), &rec);
map { [shift, shift] } @​_
}

rec(1, 1)

I can confirm that I get this in Perl 5.16.0 but not in 5.14.2. But I
can't understand your program well enough (e.g., why are you assigning
to @​_ ?) to help further.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented May 11, 2013

From @jkeenan

On Sat May 11 02​:02​:53 2013, victor.adam@​derpymail.org wrote​:

Hello,

As I said, I originally discovered the bug while golfing. Assigning to
@​_
saved a few keystrokes. I just experemented further, and it turns out
the
bug can be reproduced without this assignment​:

sub rec {
$depth++;
return @​_ if $depth == 16;
@​tree = ((grep { $_[$_] == $depth } 0..$#_), &rec);
map { [shift @​tree, shift @​tree] } @​tree;
}

rec(1, 1);

Note that the block passed to map completely ignores $_. Since each
iteration consumes 2 elements of @​tree, the sensible thing to do would
be
to iterate over 1..@​tree/2 —*way *too many keystrokes. However, the
problem
only occurs when iterating over @​tree. I'm aware that this kind of
hack is
unlikely to occur in production code.

Thank you,

Victor Adam

Thanks for the follow-up. As Dave Mitchell noted, this falls into a
class of known problems that do not have an easy solution. I have
marked the ticket as such.

Thank you very much.
Jim Keenan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants