Open p5pRT opened 19 years ago
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)
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
The RT System itself - Status changed from 'new' to 'open'
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
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
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
Migrated from rt.perl.org#34180 (status was 'open')
Searchable as RT34180$