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: