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

Bizarre copy of ARRAY in list assignment #10687

Open
p5pRT opened this issue Oct 3, 2010 · 7 comments
Open

Bizarre copy of ARRAY in list assignment #10687

p5pRT opened this issue Oct 3, 2010 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 3, 2010

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

Searchable as RT78186$

@p5pRT
Copy link
Author

p5pRT commented Oct 3, 2010

From ghewson@wormhole.me.uk

This is a bug report for perl from ghewson@​wormhole.me.uk,
generated with the help of perlbug 1.39 running under perl 5.13.5.


https://rt.cpan.org:443/Public/Bug/Display.html?id=50447 is a report on
Devel​::StackTrace, where message "Bizzare copy of **** in stack args" is
issued. The report includes a test case. The author of Devel​::StackTrace,
Dave Rolsky, believes this is due to a bug in the perl core, and should be
reported there, so that's what I'm doing.

I've written a stripped-down amalgamation of the test case, written by
Alexandre Gorobets, and Devel​::StackTrace. I ran it under perl 5.8.8,
5.10.0, 5.12.2 and 5.13.5. Under 5.13.5, the error message is
"Bizarre copy of ARRAY in list assignment at ./bug line 55." Under the other
versions, the message says "aassign" instead of "list assignment".

Graeme Hewson


#!/home/ghewson/perl-5-13.5/bin/perl

use warnings;
use strict;

s1();

sub s1 {
  my $href;
  $href->{'key'} = [ 'a' ];
 
  call_with_args(
  $href,
  sub {
  $href->{'key'} = [ 'b' ];
  call_trace( sub { 1; } );
  }
  );
}

sub call_with_args {
  my ($h, $func) = @​_;
  $func->( @​{$h->{'key'}} );
}

sub call_trace {
  my $s = trace();
}

sub trace
{
  # %p is not referenced, but for "Bizarre copy" message to appear,
  # it must be present and the number of keys must be 1.

  my %p = ( 'x' => 'c' );

  # Again, $s is not referenced, but is needed for error to occur.

  my $s = {

  # If this commented out, get "Bizarre copy of HASH" instead of "ARRAY".
  f => [],
  };

  my $level = 0;
  while ( my @​c =
  do {
  # Error disappears if "package DB" is commented out
  package DB;
  caller($level++)
  } )
  {
  print "$c[3] at line $c[2]\n";
# Error occurs at following line​:
  my @​a = @​DB​::args;

  }

}



Flags​:
  category=core
  severity=low


Site configuration information for perl 5.13.5​:

Configured by ghewson at Sat Oct 2 14​:03​:25 BST 2010.

Summary of my perl5 (revision 5 version 13 subversion 5) configuration​:
 
  Platform​:
  osname=linux, osvers=2.6.24-28-generic, archname=x86_64-linux
  uname='linux coln 2.6.24-28-generic #1 smp wed aug 25 14​:39​:49 utc 2010 x86_64 gnulinux '
  config_args='-des -Dprefix=/home/ghewson/perl-5-13.5'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.2.4 (Ubuntu 4.2.4-1ubuntu4)', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64
  libs=-lnsl -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=/lib/libc-2.7.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.7'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'

Locally applied patches​:
 


@​INC for perl 5.13.5​:
  /home/ghewson/perl-5-13.5/lib/site_perl/5.13.5/x86_64-linux
  /home/ghewson/perl-5-13.5/lib/site_perl/5.13.5
  /home/ghewson/perl-5-13.5/lib/5.13.5/x86_64-linux
  /home/ghewson/perl-5-13.5/lib/5.13.5
  .


Environment for perl 5.13.5​:
  HOME=/home/ghewson
  LANG=en_GB.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/ghewson/bin​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games​:/home/ghewson/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Oct 4, 2010

From @iabyn

On Sun, Oct 03, 2010 at 10​:13​:21AM -0700, Graeme Hewson wrote​:

https://rt.cpan.org:443/Public/Bug/Display.html?id=50447 is a report on
Devel​::StackTrace, where message "Bizzare copy of **** in stack args" is
issued. The report includes a test case. The author of Devel​::StackTrace,
Dave Rolsky, believes this is due to a bug in the perl core, and should be
reported there, so that's what I'm doing.

I've written a stripped-down amalgamation of the test case, written by
Alexandre Gorobets, and Devel​::StackTrace. I ran it under perl 5.8.8,
5.10.0, 5.12.2 and 5.13.5. Under 5.13.5, the error message is
"Bizarre copy of ARRAY in list assignment at ./bug line 55." Under the other
versions, the message says "aassign" instead of "list assignment".

Thanks for the report.
The 'Bizzare copy' when reading from @​DB​::args is an indication that
one of the elements of @​DB​::args has been prematurely freed and then
reallocated. thus can happen becuase perl doesn't reference count
items on the stack (such as function call arguments), so they can be freed
mid-flight.

You code does essentially the equivalent of the following​:

Your sample code can be reduced to

  my $a;
  $a = [ 'a' ];

  f(@​$a);

  sub f {
  $a = [ 'b' ]; # whoops, arg0 freed

  package DB;
  my @​c = caller(0);
  use Devel​::Peek;
  Dump $DB​::args[0];
  }

which outputs

  SV = UNKNOWN(0xff) (0xa95290) at 0xa75b88
  REFCNT = 0
  FLAGS = ()

demonstrating that arg 0 of f() has been freed.

This is unfortunately not realistically fixable.

--
My get-up-and-go just got up and went.

@p5pRT
Copy link
Author

p5pRT commented Oct 4, 2010

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

@p5pRT
Copy link
Author

p5pRT commented Oct 4, 2010

From @autarch

Is there a way to detect this and avoid the error message, at least? Is
there something one could check when iterating over DB​::args() ?

@p5pRT
Copy link
Author

p5pRT commented Oct 4, 2010

From ghewson@wormhole.me.uk

On Monday 04 October 2010 19​:33​:17 Dave Rolsky via RT wrote​:

Is there a way to detect this and avoid the error message, at least? Is
there something one could check when iterating over DB​::args() ?

Sorry, this is outside my experience. I haven't looked at Carp 1.18 yet.

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2012

From @jkeenan

On Mon Oct 04 08​:16​:28 2010, davem wrote​:

Your sample code can be reduced to

my $a;
$a = \[ 'a' \];

f\(@​$a\);

sub f \{
$a = \[ 'b' \]; \# whoops\, arg0 freed

package DB;
my @​c = caller\(0\);
use Devel​::Peek;
Dump $DB​::args\[0\];
\}

which outputs

SV = UNKNOWN\(0xff\) \(0xa95290\) at 0xa75b88
  REFCNT = 0
  FLAGS = \(\)

demonstrating that arg 0 of f() has been freed.

But when I ran that code (Perl 5.14.2/Darwin), I got different results​:

$ cat 78186.pl
my $a;
$a = [ 'a' ];

f(@​$a);

sub f {
  $a = [ 'b' ]; # whoops, arg0 freed
 
  package DB;
  my @​c = caller(0);
  use Devel​::Peek;
  Dump $DB​::args[0];
}

$ perl 78186.pl
SV = NULL(0x0) at 0x1804110
  REFCNT = 1
  FLAGS = ()

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2012

From @jkeenan

On Sun Apr 22 19​:14​:09 2012, jkeenan wrote​:

But next, trying it on Linux/i386, I got similar results to davem​:

$ perl 78186.pl
SV = UNKNOWN(0xff) (0x817ab88) at 0x817a1d8
  REFCNT = 0
  FLAGS = ()

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

No branches or pull requests

2 participants