Skip Menu |
Report information
Id: 112104
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: lasse.makholm [at] gmail.com
Cc:
AdminCc:

Operating System: Linux
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.15.9
Fixed In: (no value)



Subject: die($object) in thread reblesses $object into main and breaks stringification
Date: Thu, 29 Mar 2012 11:52:01 +0200
To: perlbug [...] perl.org
From: Lasse Makholm <lasse.makholm [...] gmail.com>
Download (untitled) / with headers
text/plain 3.9k
This is a bug report for perl from lasse.makholm@gmail.com, generated with the help of perlbug 1.39 running under perl 5.15.9. ----------------------------------------------------------------- When passing an object to die() in a thread, the object gets reblessed into main before the thread termination warning is printed. This breaks exception stringification: $ perl -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" }); $t->join' Thread 1 terminated abnormally: main=HASH(0x1576a48) at -e line 1. $ The exception is cloned correctly into the main thread though: $ perl -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" }); $t->join; die $t->error' Thread 1 terminated abnormally: main=HASH(0x10b7d00) at -e line 1. Foo=HASH(0xfb7f90) $ I haven't been able to find any mentioning of this issue anywhere but snooping around the source seems to indicate that this behaviour has been around since perl-5.8.0-9301-g955c272. The culprit is in threads.xs: /* If ERRSV is an object, remember the classname and then * rebless into 'main' so it will survive 'cloning' */ if (sv_isobject(thread->err)) { thread->err_class = HvNAME(SvSTASH(SvRV(thread->err))); sv_bless(thread->err, gv_stashpv("main", 0)); } ...but that was added for a reason it seems. I'm not sure what the appropriate fix should be. ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.15.9: Configured by lasse at Wed Mar 28 17:57:13 CEST 2012. Summary of my perl5 (revision 5 version 15 subversion 9) configuration: Commit id: 63429d50b5b6c112d030f925ddce05a84d042758 Platform: osname=linux, osvers=3.0.0-16-generic, archname=x86_64-linux uname='linux plystrofyf 3.0.0-16-generic #28-ubuntu smp fri jan 27 17:44:39 utc 2012 x86_64 x86_64 x86_64 gnulinux ' config_args='-de -Dusedevel' 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.6.1', 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/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib libs=-lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.13' 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.15.9: lib /usr/local/lib/perl5/site_perl/5.15.9/x86_64-linux /usr/local/lib/perl5/site_perl/5.15.9 /usr/local/lib/perl5/5.15.9/x86_64-linux /usr/local/lib/perl5/5.15.9 . --- Environment for perl 5.15.9: HOME=/home/lasse LANG=da_DK.UTF-8 LANGUAGE=en_GB:en LC_COLLATE=en_GB.UTF-8 LC_CTYPE=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games PERL_BADLANG (unset) SHELL=/bin/bash
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.8k
On Thu Mar 29 02:52:26 2012, lasse.makholm@gmail.com wrote: Show quoted text
> This is a bug report for perl from lasse.makholm@gmail.com, > generated with the help of perlbug 1.39 running under perl 5.15.9. > > > ----------------------------------------------------------------- > > When passing an object to die() in a thread, the object gets > reblessed into main before the thread termination warning is > printed. This breaks exception stringification: > > $ perl -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" > }); $t->join' > Thread 1 terminated abnormally: main=HASH(0x1576a48) at -e line 1. > $ > > The exception is cloned correctly into the main thread though: > > $ perl -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" > }); $t->join; die $t->error' > Thread 1 terminated abnormally: main=HASH(0x10b7d00) at -e line 1. > Foo=HASH(0xfb7f90) > $ > > I haven't been able to find any mentioning of this issue anywhere > but snooping around the source seems to indicate that this > behaviour has been around since perl-5.8.0-9301-g955c272. > > The culprit is in threads.xs: > > /* If ERRSV is an object, remember the classname and then > * rebless into 'main' so it will survive 'cloning' > */ > if (sv_isobject(thread->err)) { > thread->err_class = HvNAME(SvSTASH(SvRV(thread-
> >err)));
> sv_bless(thread->err, gv_stashpv("main", 0)); > } > > ...but that was added for a reason it seems. I'm not sure what > the appropriate fix should be.
This appears to be a 5.8.9 regression: $ perl5.8.8 -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" }); $t->join' thread failed to start: Foo=HASH(0x87242c) at -e line 2. $ perl5.8.9 -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" }); $t->join' Thread 1 terminated abnormally: main=HASH(0x87fdac) at -e line 2. -- Father Chrysostomos
CC: perl5-porters [...] perl.org
Subject: Re: [perl #112104] die($object) in thread reblesses $object into main and breaks stringification
Date: Sun, 1 Apr 2012 08:15:56 +0100
To: Father Chrysostomos via RT <perlbug-followup [...] perl.org>, "Jerry D. Hedden" <jdhedden [...] cpan.org>
From: Nicholas Clark <nick [...] ccl4.org>
Download (untitled) / with headers
text/plain 2.4k
On Thu, Mar 29, 2012 at 04:06:00PM -0700, Father Chrysostomos via RT wrote: Show quoted text
> On Thu Mar 29 02:52:26 2012, lasse.makholm@gmail.com wrote:
> > This is a bug report for perl from lasse.makholm@gmail.com, > > generated with the help of perlbug 1.39 running under perl 5.15.9.
Show quoted text
> > When passing an object to die() in a thread, the object gets > > reblessed into main before the thread termination warning is > > printed. This breaks exception stringification:
Show quoted text
> > I haven't been able to find any mentioning of this issue anywhere > > but snooping around the source seems to indicate that this > > behaviour has been around since perl-5.8.0-9301-g955c272. > > > > The culprit is in threads.xs: > > > > /* If ERRSV is an object, remember the classname and then > > * rebless into 'main' so it will survive 'cloning' > > */ > > if (sv_isobject(thread->err)) { > > thread->err_class = HvNAME(SvSTASH(SvRV(thread-
> > >err)));
> > sv_bless(thread->err, gv_stashpv("main", 0)); > > } > > > > ...but that was added for a reason it seems. I'm not sure what > > the appropriate fix should be.
I don't know either, but the idea of reblessing as implemented in that code doesn't look sane. However, this may start to touch on a deeper fundamental unsolvable problem of ithreads - you can't be 100% sure *how* to clone something back into the parent thread, because the object in the child thread is blessed into a class not present in the parent thread, and there's no 100% sure way to "autoload" the implementation of a class. Show quoted text
> This appears to be a 5.8.9 regression: > > $ perl5.8.8 -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" > }); $t->join' > thread failed to start: Foo=HASH(0x87242c) at -e line 2. > $ perl5.8.9 -e 'use threads; $t = threads->create(sub { die bless {}, "Foo" > }); $t->join' > Thread 1 terminated abnormally: main=HASH(0x87fdac) at -e line 2.
Well, as implied by commit hash referenced in the bug report, it's a regression as a side effect of threads 1.54, and 5.8.9 updated to include that module. The XS code in question was added with this: commit 955c272e505839f6c86e2403961d6237672ec9af Author: Jerry D. Hedden <jdhedden@cpan.org> Date: Thu Dec 14 03:17:47 2006 -0800 threads 1.54 - Adds ->error() method From: "Jerry D. Hedden" <jdhedden@yahoo.com> Message-ID: <20061214191748.98286.qmail@web30209.mail.mud.yahoo.com> p4raw-id: //depot/perl@29557 Nicholas Clark
To: perl5-porters [...] perl.org
Date: Thu, 14 Dec 2017 04:38:13 +0000
From: Zefram <zefram [...] fysh.org>
Subject: Re: [perl #112104] die($object) in thread reblesses $object into main and breaks stringification
Download (untitled) / with headers
text/plain 585b
Lasse Makholm wrote: Show quoted text
>I haven't been able to find any mentioning of this issue anywhere
The "bugs and limitations" section of the threads.pm documentation has a note that returning blessed objects doesn't work. As discussed on [perl #96538], making it work would involve maintaining more of a link between objects in different threads than we can handle. The reblessing is crap, but so is the undef that you get by returning a blessed object as your non-error result. To return blessed objects you'll have to arrange your own serialisation. This ticket should be closed. -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org