perl5 icon indicating copy to clipboard operation
perl5 copied to clipboard

unlocking in forked child is fragile

Open p5pRT opened this issue 12 years ago • 5 comments

Migrated from rt.perl.org#119663 (status was 'open')

Searchable as RT119663$

p5pRT avatar Sep 07 '13 18:09 p5pRT

From @jmdh

This is a bug report for perl from dom@​earth.li, generated with the help of perlbug 1.39 running under perl 5.14.2.


As discussed at <http​://bugs.debian.org/cgi-bin/bugreport.cgi?bug=677046> Petr Salinger <Petr.Salinger@​seznam.cz> suggests that the attached patch (or something like it) be applied. The patch was originally authored in order to fix a Debian GNU/kFreeBSD build failure, but may still be relevant (the generated files will not apply to blead).



Flags​:   category=core   severity=low


Site configuration information for perl 5.14.2​:

Configured by Debian Project at Fri Apr 12 09​:56​:36 UTC 2013.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration​:  
  Platform​:   osname=linux, osvers=2.6.32-5-686-bigmem, archname=i486-linux-gnu-thread-multi-64int   uname='linux murphy 2.6.32-5-686-bigmem #1 smp mon feb 25 01​:53​:47 utc 2013 i686 gnulinux '   config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Dldflags= -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14 -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2 -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.14.2 -des'   hint=recommended, useposix=true, d_sigaction=define   useithreads=define, usemultiplicity=define   useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef   use64bitint=define, use64bitall=undef, uselongdouble=undef   usemymalloc=n, bincompat5005=undef   Compiler​:   cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',   optimize='-O2 -g',   cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include'   ccversion='', gccversion='4.7.2', gccosandvers=''   intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678   d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12   ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8   alignbytes=4, prototype=define   Linker and Libraries​:   ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'   libpth=/usr/local/lib /lib/i386-linux-gnu /lib/../lib /usr/lib/i386-linux-gnu /usr/lib/../lib /lib /usr/lib   libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt   perllibs=-ldl -lm -lpthread -lc -lcrypt   libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2   gnulibc_version='2.13'   Dynamic Linking​:   dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'   cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches​:  


@​INC for perl 5.14.2​:   /etc/perl   /usr/local/lib/perl/5.14.2   /usr/local/share/perl/5.14.2   /usr/lib/perl5   /usr/share/perl5   /usr/lib/perl/5.14   /usr/share/perl/5.14   /usr/local/lib/site_perl   .


Environment for perl 5.14.2​:   HOME=/home/dom   LANG=en_GB.UTF-8   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=~/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/local/games​:/usr/games   PERL_BADLANG (unset)   SHELL=/bin/bash

p5pRT avatar Sep 07 '13 18:09 p5pRT

From @jmdh

0001-Reinit-mutex-after-a-fork.patch
From ad6bd76bce15cf552e86a9648c357fe29233ec63 Mon Sep 17 00:00:00 2001
From: Niko Tyni <[email protected]>
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


p5pRT avatar Sep 07 '13 18:09 p5pRT

From @Leont

On Sat, Sep 7, 2013 at 8​:17 PM, Dominic Hargreaves < perlbug-followup@​perl.org> wrote​:

As discussed at <http​://bugs.debian.org/cgi-bin/bugreport.cgi?bug=677046> Petr Salinger <Petr.Salinger@​seznam.cz> suggests that the attached patch (or something like it) be applied. The patch was originally authored in order to fix a Debian GNU/kFreeBSD build failure, but may still be relevant (the generated files will not apply to blead).

Can't say I like the patch. POSIX seems to confirm my gut feeling​: "Alternatively, some libraries might have been able to supply just a *child*routine that reinitializes the mutexes This approach is not possible, though, because implementations are allowed to fail **_init()* and * *_destroy()* calls for mutexes and locks if the mutex or lock is still locked. In this case, the *child* routine is not able to reinitialize the mutexes and locks."

I really think this was a bug in kFreeBSD, and given that it has apparently been fixed there already I don't think we should apply this patch to blead.

Leon

p5pRT avatar Sep 07 '13 20:09 p5pRT

The RT System itself - Status changed from 'new' to 'open'

p5pRT avatar Sep 07 '13 20:09 p5pRT

Haiku is affected by this problem. There, the unlock in the child doesn't work at all because it fails with EPERM. Apparently, Haiku uses ERRORCHECK style mutexes by default.

Although perldoc perlhaiku currently says that threading isn't supported on Haiku, I managed to build it with a few patches (see https://github.com/haikuports/haikuports/pull/10626). In https://github.com/haikuports/haikuports/pull/10763 I applied a version of the patch from this issue to the build.

In the version without threads we used before, there were XS handshake failures with SDL_perl, which was fixed by enabling threads (and/or upgrading to the current perl version).

jmairboeck avatar Jul 29 '24 19:07 jmairboeck