[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#628493: perl: FTBFS on kfreebsd-i386: t/op/threads failed



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   ntyni@debian.org
>From ad6bd76bce15cf552e86a9648c357fe29233ec63 Mon Sep 17 00:00:00 2001
From: Niko Tyni <ntyni@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


Reply to: