Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.98k stars 559 forks source link

Using foreach on threads::shared array crashes perl #7544

Closed p5pRT closed 20 years ago

p5pRT commented 20 years ago

Migrated from rt.perl.org#32033 (status was 'resolved')

Searchable as RT32033$

p5pRT commented 20 years ago

From sroy@search-box.com

This is a bug report for perl from sroy@​searchbox.parc.xerox.com\, generated with the help of perlbug 1.35 running under perl v5.8.5.


The folllowing test program crashes perl​:


use threads; use threads​::shared; my @​list : shared; push(@​list\, &share(new A)); foreach $a (@​list) {   $a->{n}; # \<-- needed to produce segmentation fault   print "$a\n"; # \<-- segmentation fault }

package A; sub new {   return bless {}; }


Additional observations​:

1) Replacing the foreach loop with a for loop seems to work   around the bug​:

  for ($i = 0; $i \< @​list; $i++) {   $a = $list[$i]

2) Removing the bless eliminates the crash but generates some   scalar leaked warnings.

Scott



Flags​:   category=core   severity=high


Site configuration information for perl v5.8.5​:

Configured by sroy at Mon Oct 18 11​:06​:57 PDT 2004.

Summary of my perl5 (revision 5 version 8 subversion 5) configuration​:   Platform​:   osname=linux\, osvers=2.4.25-1-386\, archname=i686-linux-thread-multi   uname='linux searchbox.parc.xerox.com 2.4.25-1-386 #2 wed apr 14 19​:38​:08 est 2004 i686 gnulinux '   config_args=''   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=define use5005threads=undef useithreads=define usemultiplicity=define   useperlio=define d_sfio=undef uselargefiles=define usesocks=undef   use64bitint=undef use64bitall=undef uselongdouble=undef   usemymalloc=n\, bincompat5005=undef   Compiler​:   cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\,   optimize='-O2'\,   cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -pipe -I/usr/local/include'   ccversion=''\, gccversion='3.3.4 (Debian 1​:3.3.4-13)'\, gccosandvers=''   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12   ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8   alignbytes=4\, prototype=define   Linker and Libraries​:   ld='cc'\, ldflags =' -L/usr/local/lib'   libpth=/usr/local/lib /lib /usr/lib   libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc   perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc   libc=/lib/libc-2.3.2.so\, so=so\, useshrplib=false\, libperl=libperl.a   gnulibc_version='2.3.2'   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E'   cccdlflags='-fpic'\, lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:  


@​INC for perl v5.8.5​:   /usr/local/lib/perl5/5.8.5/i686-linux-thread-multi   /usr/local/lib/perl5/5.8.5   /usr/local/lib/perl5/site_perl/5.8.5/i686-linux-thread-multi   /usr/local/lib/perl5/site_perl/5.8.5   /usr/local/lib/perl5/site_perl   .


Environment for perl v5.8.5​:   HOME=/home/sroy   LANG (unset)   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=/home/sroy/cvs/searchbox/server​:/usr/local/bin​:/usr/bin​:/bin​:/usr/bin/X11​:/usr/games   PERL_BADLANG (unset)   SHELL=/bin/bash

p5pRT commented 20 years ago

From @rgs

sroy@​search-box.com (via RT) wrote​:

The folllowing test program crashes perl​:

------------------- use threads; use threads​::shared; my @​list : shared; push(@​list\, &share(new A)); foreach $a (@​list) { $a->{n}; # \<-- needed to produce segmentation fault

$a is aliased to the element of @​list; @​list being shared\, its elements need to be too\, but perl doesn't check this.

print "$a\\n";    \# \<\-\- segmentation fault

}

package A; sub new { return bless {}; }

With a debugging threaded bleadperl\, your program gives this output :

__ANON__=HASH(0x8246e44) Assertion my_perl == PL_sharedsv_space failed​: file "shared.xs"\, line 181.

showing where the crash occurs (with non-debugging perls).

But using &share to bypass prototype checking is evil\, as share is intended to be used on variables only.

Additional observations​:

1) Replacing the foreach loop with a for loop seems to work around the bug​:

Because aliasing is no longer involved.

2) Removing the bless eliminates the crash but generates some scalar leaked warnings.

p5pRT commented 20 years ago

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

p5pRT commented 20 years ago

From hsr@cs.stanford.edu

But using &share to bypass prototype checking is evil\, as share is intended to be used on variables only.

It still crashes even when I get rid of share() and try to declare everything in the variable declarations. For example\, the following still crashes​:


#!/usr/bin/perl # # BUG​: foreach crashes on shared hashref #

use threads; use threads​::shared;

my @​list : shared; my %a : shared; my $a : shared; $a = \%a; bless($a); push(@​list\, $a); foreach $a (@​list) {   $a->{n}; # \<-- needed to produce segmentation fault   print "$a\n"; # \<-- segmentation fault }


Is there no way\, then\, to have a shared list of references? Am I simply missing something in my syntax?

Scott

p5pRT commented 20 years ago

From @schwern

On Mon\, Oct 18\, 2004 at 09​:10​:06PM -0000\, sroy @​ search-box. com wrote​:

Additional observations​:

Additional\, additional observations.

5.8.1RC3 (that which ships with OS X) does not crash.

Changing $a to $c still crashes (thinking maybe it had to do with the   semi-mystic nature of $a and $b).

Making $a lexical still crashes.

Copying $a to $d and then using $d does not crash.

  foreach $a (@​list) {   my $d = $a;   $d->{n};   print "$d\n";   }

Conclusion​: Its got something to do with the aliasing nature of foreach.

-- Michael G Schwern schwern@​pobox.com http​://www.pobox.com/~schwern/ Milk may build strong bones\, but adhesives are cement for the mind.   http​://www.goats.com/archive/990103.html

p5pRT commented 20 years ago

From @iabyn

On Thu\, Oct 21\, 2004 at 10​:22​:48AM -0700\, Scott Roy wrote​:

It still crashes even when I get rid of share() and try to declare everything in the variable declarations. For example\, the following still crashes​:

---- #!/usr/bin/perl # # BUG​: foreach crashes on shared hashref #

use threads; use threads​::shared;

my @​list : shared; my %a : shared; my $a : shared; $a = \%a; bless($a); push(@​list\, $a); foreach $a (@​list) { $a->{n}; # \<-- needed to produce segmentation fault print "$a\n"; # \<-- segmentation fault } ----

Fixed in bleedperl by the change below.

-- "You're so sadly neglected\, and often ignored. A poor second to Belgium\, When going abroad."   -- Monty Python - "Finland"

Change 23438 by davem@​davem-splatty on 2004/10/30 23​:25​:37

  [perl #32033] Using foreach on threads​::shared array crashes perl   The FETCH code for shared aggregate elements could leak a shared RV   address into a private SV. RVs are now handled specially\, in the   same way that they already were for scalar shared magic.

Affected files ...

... //depot/perl/ext/threads/shared/shared.xs#47 edit

Differences ...

==== //depot/perl/ext/threads/shared/shared.xs#47 (text) ====

@​@​ -639\,8 +639\,18 @​@​   CALLER_CONTEXT;   if (svp) {   /* Exists in the array */ - target = Perl_sharedsv_associate(aTHX_ &sv\, *svp\, target); - sv_setsv(sv\, *svp); + if (SvROK(*svp)) { + SV *obj = Nullsv; + Perl_sharedsv_associate(aTHX_ &obj\, SvRV(*svp)\, NULL); + sv_setsv_nomg(sv\, &PL_sv_undef); + SvRV(sv) = obj; + SvROK_on(sv); + SvSETMAGIC(sv); + } + else { + target = Perl_sharedsv_associate(aTHX_ &sv\, *svp\, target); + sv_setsv(sv\, *svp); + }   }   else {   /* Not in the array */

p5pRT commented 20 years ago

@iabyn - Status changed from 'open' to 'resolved'