Perl / perl5

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

segfault in perl_clone under ithreads and custom PerlIO layer #7805

Open p5pRT opened 19 years ago

p5pRT commented 19 years ago

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

Searchable as RT34180$

p5pRT commented 19 years ago

From stas@stason.org

Created by stas@rabbit.stason.org

This is a bug report for perl from stas@​rabbit.stason.org\, generated with the help of perlbug 1.35 running under perl v5.8.6.

-----------------------------------------------------------------

We have yet another chicken-n-egg problem with perl_clone. If you do a simple​:

use threads; my $thread = threads->create(sub {}\, undef)

and STDOUT is opened to some PerlIO layer\, an attempt to clone it will be performed. The problem is that this cloning happens too early​:

perl-5.8.6/sv.c​:10859​:

#ifdef PERLIO_LAYERS   /* Clone PerlIO tables as soon as we can handle general xx_dup() */   PerlIO_clone(aTHX_ proto_perl\, param); #endif

xx_dup() works for the core perl\, but it doesn't take into account that a custom PerlIO layer may need other bits set in my_perl. In the above case I get a segfault because PL_defstash is bogus. it's set only after PerlIO_clone is called. (line 10954) I get this segfault​:

#0 0x404c8a04 in Perl_gv_fetchpv (my_perl=0x85e6540\,   nambeg=0x404939d0 "Apache​::RequestRec"\, add=1\, sv_type=11) at gv.c​:670 #1 0x40479f37 in PerlIOApache_getarg (my_perl=0x85e6540\, f=0x828634c\,   param=0xbfffe9c0\, flags=1) at modperl_io_apache.c​:87 #2 0x405c55b5 in PerlIOBase_dup (my_perl=0x85e6540\, f=0x83576c4\, o=0x828634c\,   param=0xbfffe9c0\, flags=1) at perlio.c​:2187 #3 0x405c1e50 in PerlIO_fdupopen (my_perl=0x85e6540\, f=0x828634c\,   param=0xbfffe9c0\, flags=1) at perlio.c​:542 #4 0x40555faf in Perl_fp_dup (my_perl=0x85e6540\, fp=0x828634c\, type=0 '\0'\,   param=0xbfffe9c0) at sv.c​:9505 #5 0x405c22a5 in PerlIO_clone (my_perl=0x85e6540\, proto=0x8abfb10\,   param=0xbfffe9c0) at perlio.c​:650 #6 0x4055a6fe in perl_clone (proto_perl=0x8abfb10\, flags=2) at sv.c​:10859 #7 0x4078aa50 in Perl_ithread_create (my_perl=0x8abfb10\, obj=0x0\,   classname=0x82dc948 "threads"\, init_function=0x8153728\, params=0x815377c)   at threads.xs​:426 #8 0x4078b3f7 in XS_threads_new (my_perl=0x8abfb10\, cv=0x82f0698)   at threads.xs​:687

the segfault happens here​:

  if (!stash)   stash = PL_defstash;   if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */

PL_defstash == 0xabababab here

PerlIOApache_getarg happens to call gv_fetchpv which needs a valid PL_defstash.

How do we resolve this problem?

This is not the first time we hit a segfault\, due to PerlIO+clone. Some of those are still unresolved (e.g. perl -m still segfaults under threads)

Perl Info ``` Flags: category=core severity=high Site configuration information for perl v5.8.6: Configured by stas at Sun Nov 28 13:23:47 EST 2004. Summary of my perl5 (revision 5 version 8 subversion 6) configuration: Platform: osname=linux, osvers=2.6.8.1-12mdk, archname=i686-linux-thread-multi uname='linux rabbit.stason.org 2.6.8.1-12mdk #1 fri oct 1 12:53:41 cest 2004 i686 mobile intel(r) pentium(r) 4 - m cpu 2.00ghz unknown gnulinux ' config_args='-des -Dprefix=/home/stas/perl/5.8.6-ithread -Dusethreads -Doptimize=-g -Duseshrplib -Dusedevel -Accflags=-DDEBUG_LEAKING_SCALARS' 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 -DDEBUG_LEAKING_SCALARS -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-g', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUG_LEAKING_SCALARS -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)', 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 -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.3.3.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.3.3' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/home/stas/perl/5.8.6-ithread/lib/5.8.6/i686-linux-thread-multi/CORE' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl v5.8.6: /home/stas/perl/5.8.6-ithread/lib/5.8.6/i686-linux-thread-multi /home/stas/perl/5.8.6-ithread/lib/5.8.6 /home/stas/perl/5.8.6-ithread/lib/site_perl/5.8.6/i686-linux-thread-multi /home/stas/perl/5.8.6-ithread/lib/site_perl/5.8.6 /home/stas/perl/5.8.6-ithread/lib/site_perl . Environment for perl v5.8.6: HOME=/home/stas LANG=en_GB LANGUAGE=en_GB:en LC_ADDRESS=en_CA LC_COLLATE=en_GB LC_CTYPE=en_GB LC_IDENTIFICATION=en_CA LC_MEASUREMENT=en_CA LC_MESSAGES=en_GB LC_MONETARY=en_CA LC_NAME=en_CA LC_NUMERIC=en_CA LC_PAPER=en_CA LC_SOURCED=1 LC_TELEPHONE=en_CA LC_TIME=en_GB LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr//bin:/bin:/usr/bin:.:/usr/local/bin:/usr/X11R6/bin/:/usr/games:/home/stas/bin:/home/stas/bin:/usr/local/bin:/usr/X11R6/bin:/usr/java/j2re1.4.0/bin/ PERLDOC_PAGER=less -R PERL_BADLANG (unset) SHELL=/bin/tcsh ```
p5pRT commented 18 years ago

From @iabyn

On Sat\, Feb 19\, 2005 at 02​:20​:28AM -0000\, Stas Bekman wrote​:

We have yet another chicken-n-egg problem with perl_clone. If you do a simple​:

use threads; my $thread = threads->create(sub {}\, undef)

and STDOUT is opened to some PerlIO layer\, an attempt to clone it will be performed. The problem is that this cloning happens too early​:

do you have a complete script that reproduces this?

something simple like   binmode STDOUT\, '​:utf8'; didn't segfault

-- Counsellor Troi states something other than the blindingly obvious.   -- Things That Never Happen in "Star Trek" #16

p5pRT commented 18 years ago

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

p5pRT commented 18 years ago

From stas@stason.org

Dave Mitchell wrote​:

On Sat\, Feb 19\, 2005 at 02​:20​:28AM -0000\, Stas Bekman wrote​:

We have yet another chicken-n-egg problem with perl_clone. If you do a simple​:

use threads; my $thread = threads->create(sub {}\, undef)

and STDOUT is opened to some PerlIO layer\, an attempt to clone it will be performed. The problem is that this cloning happens too early​:

do you have a complete script that reproduces this?

something simple like binmode STDOUT\, '​:utf8'; didn't segfault

Under mod_perl2

package My​::Bug;

use Apache2​::RequestRec (); use Apache2​::RequestIO ();

use Apache2​::Const -compile => qw(OK);

use threads;

sub handler {   my $r = shift;

  my $thread = threads->create(sub {}\, undef);   $thread->join;

  $r->content_type('text/plain');   print 'found a bug';

  return Apache2​::Const​::OK; }

1;

and config​:

\<Location /bug>   SetHandler perl-script   PerlResponseHandler My​::Bug \

I've attached a tarball that reproduces the problem. Assuming that you've mod_perl2 installed\, unpack it and run​:

perl Makefile.PL -httpd /home/stas/httpd/prefork/bin/httpd make make test (you should get a segfault) (adjust the path to the location of your httpd)

Thanks Dave.

-- __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http​://stason.org/ mod_perl Guide ---> http​://perl.apache.org mailto​:stas@​stason.org http​://use.perl.org http​://apacheweek.com http​://modperlbook.org http​://apache.org http​://ticketmaster.com

p5pRT commented 18 years ago

From stas@stason.org

bug-reporting-skeleton-mp2.tar.gz

p5pRT commented 18 years ago

From stas@stason.org

A few other related things using APR​::PerlIO which can be used outside mod_perl​:

#foo use APR​::Pool; use APR​::PerlIO;

my $pool = APR​::Pool->new; my $filename = "/tmp/file"; open my $fh\, ">​:APR"\, $filename\, $pool or die $!;

use threads; my $thread = threads->create(sub {}\, undef); $thread->join;

% perl-5.8.6-ithread /tmp/foo *** glibc detected *** double free or corruption (!prev)​: 0x080f6518 *** Abort

% perl-5.8.7-ithread /tmp/foo

so it looks like it was fixed in 5.8.7.

The following was also segfaulting with 5.8.6\, but not with 5.8.7​:


use APR​::Pool; use APR​::PerlIO;

my $pool = APR​::Pool->new; my $filename = "/tmp/file"; close STDOUT; open STDOUT\, ">​:APR"\, $filename\, $pool or die $!;

use threads; my $thread = threads->create(sub {}\, undef); $thread->join;


Adding dup is still not good with 5.8.7​:


use APR​::Pool; use APR​::PerlIO;

my $pool = APR​::Pool->new; my $filename = "/tmp/file"; close STDOUT; open STDOUT\, ">​:APR"\, $filename\, $pool or die $!;

open OLDOUT\, ">&STDOUT" or die $!;

use threads; my $thread = threads->create(sub {}\, undef); $thread->join;


% perl-5.8.7-ithread /tmp/foo2 leaked PerlIOAPR handle 0x812d0e8 during global destruction. leaked PerlIOAPR handle 0x8065208 during global destruction.

So this is stilll an issue. Do you think it's a bug in perl?

-- __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http​://stason.org/ mod_perl Guide ---> http​://perl.apache.org mailto​:stas@​stason.org http​://use.perl.org http​://apacheweek.com http​://modperlbook.org http​://apache.org http​://ticketmaster.com

p5pRT commented 7 years ago

From @dcollinsn

Under perl 5.22 (mod_perl from the debian packages)\, Stas' third test program still segfaults​:

leaked PerlIOAPR handle 0x70008a0 during global destruction. Warning​: unable to close filehandle properly​: Illegal seek during global destruction. ==63931== Invalid read of size 4 ==63931== at 0x6375C38​: apr_file_flush (in /usr/lib/x86_64-linux-gnu/libapr-1.so.0.5.2) ==63931== by 0x6DCCB5F​: ??? (in /usr/lib/x86_64-linux-gnu/perl5/5.22/auto/APR/PerlIO/PerlIO.so) ==63931== by 0x53B74E​: Perl_PerlIO_flush (in /usr/bin/perl) ==63931== by 0x53B798​: Perl_PerlIO_flush (in /usr/bin/perl) ==63931== by 0x43EF29​: perl_destruct (in /usr/bin/perl) ==63931== by 0x41CBC2​: main (in /usr/bin/perl) ==63931== Address 0x402a108 is not stack'd\, malloc'd or (recently) free'd