On Mon, Aug 08, 2011 at 12:36:22PM +0200, Petr Salinger wrote: > >perl -Mthreads -e 'threads->create(sub {})->detach; fork' > > > >which crashes non-deterministically about half the time for me.
> The problem might be in usage of "pthread_atfork(lock, unlock, unlock)". [...] > It should suffice to add into util.c > Perl_atfork_reinit(void) > and > --- miniperlmain.c > +++ miniperlmain.c > @@ -101,7 +101,7 @@ > * --GSAR 2001-07-20 */ > PTHREAD_ATFORK(Perl_atfork_lock, > Perl_atfork_unlock, > - Perl_atfork_unlock); > + Perl_atfork_reinit); > #endif Thanks, and sorry for the delay! I finally found the time to try this out, but unfortunately it does not seem to fix the problem. Even the crash trace looks the same. (I did check that Perl_atfork_reinit() actually gets run.) I'm attaching the full patch I used based on the above. Most of it is generated by regen.pl in the source top level directory after editing embed.fnc. Running 'debian/rules perl.debug' after applying this should be enough to do a test build. Alternatively, I'm happy to try out other suggestions, hopefully with a shorter turnaround time than with this one :) Thanks again, -- Niko Tyni nt...@debian.org
>From ad6bd76bce15cf552e86a9648c357fe29233ec63 Mon Sep 17 00:00:00 2001 From: Niko Tyni <nt...@debian.org> Date: Sat, 10 Sep 2011 18:57:43 +0300 Subject: [PATCH] Reinit mutex after a fork() First try at fixing a non-deterministical crash on Debian GNU/kFreeBSD with perl -Mthreads -e 'threads->create(sub {})->detach; fork Patch by Petr Salinger, <http://bugs.debian.org/628493> --- embed.fnc | 1 + embed.h | 2 ++ global.sym | 1 + miniperlmain.c | 2 +- proto.h | 1 + util.c | 13 +++++++++++++ 6 files changed, 19 insertions(+), 1 deletions(-) diff --git a/embed.fnc b/embed.fnc index 7e00e79..d89d139 100644 --- a/embed.fnc +++ b/embed.fnc @@ -726,6 +726,7 @@ Apr |void |my_failure_exit Ap |I32 |my_fflush_all Anp |Pid_t |my_fork Anp |void |atfork_lock +Anp |void |atfork_reinit Anp |void |atfork_unlock Ap |I32 |my_lstat #if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) diff --git a/embed.h b/embed.h index 2b80af0..83cfa6f 100644 --- a/embed.h +++ b/embed.h @@ -560,6 +560,7 @@ #define my_fflush_all Perl_my_fflush_all #define my_fork Perl_my_fork #define atfork_lock Perl_atfork_lock +#define atfork_reinit Perl_atfork_reinit #define atfork_unlock Perl_atfork_unlock #define my_lstat Perl_my_lstat #if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) @@ -2970,6 +2971,7 @@ #define my_fflush_all() Perl_my_fflush_all(aTHX) #define my_fork Perl_my_fork #define atfork_lock Perl_atfork_lock +#define atfork_reinit Perl_atfork_reinit #define atfork_unlock Perl_atfork_unlock #define my_lstat() Perl_my_lstat(aTHX) #if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) diff --git a/global.sym b/global.sym index 7788338..3567ee3 100644 --- a/global.sym +++ b/global.sym @@ -304,6 +304,7 @@ Perl_my_failure_exit Perl_my_fflush_all Perl_my_fork Perl_atfork_lock +Perl_atfork_reinit Perl_atfork_unlock Perl_my_lstat Perl_my_memcmp diff --git a/miniperlmain.c b/miniperlmain.c index 39f8f19..7648eb3 100644 --- a/miniperlmain.c +++ b/miniperlmain.c @@ -101,7 +101,7 @@ main(int argc, char **argv, char **env) * --GSAR 2001-07-20 */ PTHREAD_ATFORK(Perl_atfork_lock, Perl_atfork_unlock, - Perl_atfork_unlock); + Perl_atfork_reinit); #endif if (!PL_do_undump) { diff --git a/proto.h b/proto.h index 3306ab0..baab0d3 100644 --- a/proto.h +++ b/proto.h @@ -2034,6 +2034,7 @@ PERL_CALLCONV void Perl_my_failure_exit(pTHX) PERL_CALLCONV I32 Perl_my_fflush_all(pTHX); PERL_CALLCONV Pid_t Perl_my_fork(void); PERL_CALLCONV void Perl_atfork_lock(void); +PERL_CALLCONV void Perl_atfork_reinit(void); PERL_CALLCONV void Perl_atfork_unlock(void); PERL_CALLCONV I32 Perl_my_lstat(pTHX); #if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) diff --git a/util.c b/util.c index 89fea23..f100237 100644 --- a/util.c +++ b/util.c @@ -2612,6 +2612,19 @@ Perl_atfork_unlock(void) #endif } +void +Perl_atfork_reinit(void) +{ + dVAR; +#if defined(USE_ITHREADS) + /* locks must be released in same order as in atfork_lock() */ +# ifdef MYMALLOC + MUTEX_INIT(&PL_malloc_mutex); +# endif + OP_REFCNT_INIT; +#endif +} + Pid_t Perl_my_fork(void) { -- 1.7.5.4