]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
As per POSIX, nuke all threads other than me
authorJulian Seward <jseward@acm.org>
Wed, 29 May 2002 19:26:32 +0000 (19:26 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 29 May 2002 19:26:32 +0000 (19:26 +0000)
- just before __NR_exec()
- just after __NR_fork() when I am the child
This makes OpenOffice 1.0 not have mutex-related assertion failures

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@333

coregrind/arch/x86-linux/vg_libpthread.c
coregrind/vg_include.h
coregrind/vg_libpthread.c
coregrind/vg_scheduler.c
vg_include.h
vg_libpthread.c
vg_scheduler.c
vg_syscall_mem.c

index 7c6815f59e0423665b9e5933c344fe67a63e56c2..8d5ef2f368dad6c059c684792f0ac5ed6d75434b 100644 (file)
@@ -171,6 +171,7 @@ static void not_inside ( char* msg )
    VG_(startup)();
 }
 
+__attribute__((noreturn))
 void vgPlain_unimp ( char* what )
 {
    char* ig = "valgrind's libpthread.so: UNIMPLEMENTED FUNCTION: ";
@@ -896,6 +897,9 @@ void pthread_testcancel ( void )
 
 
 /*-------------------*/
+/* If this is indeed used by LinuxThreads to implement thread nuking
+   post fork and pre exec, we should really nuke em, not do
+   pthread_cancel. */
 static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER;
 
 void __pthread_kill_other_threads_np ( void )
@@ -1079,10 +1083,9 @@ int __pthread_atfork ( void (*prepare)(void),
                        void (*parent)(void),
                        void (*child)(void) )
 {
-   static int moans = N_MOANS;
-   if (moans-- > 0) 
-      ignored("pthread_atfork");
-   return 0;
+   /* We have to do this properly or not at all; faking it isn't an
+      option. */
+   vgPlain_unimp("__pthread_atfork");
 }
 
 
index 290fbec7395f7c24e5120e0be08d868227b502f5..840282b2002c7a16a2694f6a0e8a8915ecf062db 100644 (file)
@@ -691,6 +691,9 @@ extern ThreadId VG_(get_current_tid) ( void );
    error message generation. */
 extern ThreadId VG_(identify_stack_addr)( Addr a );
 
+/* Nuke all threads except tid. */
+extern void VG_(nuke_all_threads_except) ( ThreadId me );
+
 
 /* Return codes from the scheduler. */
 typedef
index 7c6815f59e0423665b9e5933c344fe67a63e56c2..8d5ef2f368dad6c059c684792f0ac5ed6d75434b 100644 (file)
@@ -171,6 +171,7 @@ static void not_inside ( char* msg )
    VG_(startup)();
 }
 
+__attribute__((noreturn))
 void vgPlain_unimp ( char* what )
 {
    char* ig = "valgrind's libpthread.so: UNIMPLEMENTED FUNCTION: ";
@@ -896,6 +897,9 @@ void pthread_testcancel ( void )
 
 
 /*-------------------*/
+/* If this is indeed used by LinuxThreads to implement thread nuking
+   post fork and pre exec, we should really nuke em, not do
+   pthread_cancel. */
 static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER;
 
 void __pthread_kill_other_threads_np ( void )
@@ -1079,10 +1083,9 @@ int __pthread_atfork ( void (*prepare)(void),
                        void (*parent)(void),
                        void (*child)(void) )
 {
-   static int moans = N_MOANS;
-   if (moans-- > 0) 
-      ignored("pthread_atfork");
-   return 0;
+   /* We have to do this properly or not at all; faking it isn't an
+      option. */
+   vgPlain_unimp("__pthread_atfork");
 }
 
 
index c6314564813d27f9d079b09269b2e3991f908c84..0e2ce294b62441906c6b0fdadba3a3dbec919a02 100644 (file)
@@ -1686,6 +1686,24 @@ void maybe_rendezvous_joiners_and_joinees ( void )
 }
 
 
+/* Nuke all threads other than tid.  POSIX specifies that this should
+   happen in __NR_exec, and after a __NR_fork() when I am the child,
+   as POSIX requires. */
+void VG_(nuke_all_threads_except) ( ThreadId me )
+{
+   ThreadId tid;
+   for (tid = 1; tid < VG_N_THREADS; tid++) {
+      if (tid == me
+          || VG_(threads)[tid].status == VgTs_Empty) 
+         continue;
+      VG_(printf)(
+         "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
+      VG_(threads)[tid].status = VgTs_Empty;
+      cleanup_after_thread_exited( tid );
+   }
+}
+
+
 /* -----------------------------------------------------------
    Thread CREATION, JOINAGE and CANCELLATION: REQUESTS
    -------------------------------------------------------- */
index 290fbec7395f7c24e5120e0be08d868227b502f5..840282b2002c7a16a2694f6a0e8a8915ecf062db 100644 (file)
@@ -691,6 +691,9 @@ extern ThreadId VG_(get_current_tid) ( void );
    error message generation. */
 extern ThreadId VG_(identify_stack_addr)( Addr a );
 
+/* Nuke all threads except tid. */
+extern void VG_(nuke_all_threads_except) ( ThreadId me );
+
 
 /* Return codes from the scheduler. */
 typedef
index 7c6815f59e0423665b9e5933c344fe67a63e56c2..8d5ef2f368dad6c059c684792f0ac5ed6d75434b 100644 (file)
@@ -171,6 +171,7 @@ static void not_inside ( char* msg )
    VG_(startup)();
 }
 
+__attribute__((noreturn))
 void vgPlain_unimp ( char* what )
 {
    char* ig = "valgrind's libpthread.so: UNIMPLEMENTED FUNCTION: ";
@@ -896,6 +897,9 @@ void pthread_testcancel ( void )
 
 
 /*-------------------*/
+/* If this is indeed used by LinuxThreads to implement thread nuking
+   post fork and pre exec, we should really nuke em, not do
+   pthread_cancel. */
 static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER;
 
 void __pthread_kill_other_threads_np ( void )
@@ -1079,10 +1083,9 @@ int __pthread_atfork ( void (*prepare)(void),
                        void (*parent)(void),
                        void (*child)(void) )
 {
-   static int moans = N_MOANS;
-   if (moans-- > 0) 
-      ignored("pthread_atfork");
-   return 0;
+   /* We have to do this properly or not at all; faking it isn't an
+      option. */
+   vgPlain_unimp("__pthread_atfork");
 }
 
 
index c6314564813d27f9d079b09269b2e3991f908c84..0e2ce294b62441906c6b0fdadba3a3dbec919a02 100644 (file)
@@ -1686,6 +1686,24 @@ void maybe_rendezvous_joiners_and_joinees ( void )
 }
 
 
+/* Nuke all threads other than tid.  POSIX specifies that this should
+   happen in __NR_exec, and after a __NR_fork() when I am the child,
+   as POSIX requires. */
+void VG_(nuke_all_threads_except) ( ThreadId me )
+{
+   ThreadId tid;
+   for (tid = 1; tid < VG_N_THREADS; tid++) {
+      if (tid == me
+          || VG_(threads)[tid].status == VgTs_Empty) 
+         continue;
+      VG_(printf)(
+         "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
+      VG_(threads)[tid].status = VgTs_Empty;
+      cleanup_after_thread_exited( tid );
+   }
+}
+
+
 /* -----------------------------------------------------------
    Thread CREATION, JOINAGE and CANCELLATION: REQUESTS
    -------------------------------------------------------- */
index 0c5d88861e4febb8d0da8fc42cd620792fa4bcba..518c54aae23b757f97806e0197e09c027890a79c 100644 (file)
@@ -895,6 +895,9 @@ void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid )
          if (VG_(clo_trace_syscalls)) 
             VG_(printf)("execve ( %p(%s), %p, %p ) --- NOT CHECKED\n", 
                         arg1, arg1, arg2, arg3);
+         /* Resistance is futile.  Nuke all other threads.  POSIX
+            mandates this. */
+            VG_(nuke_all_threads_except)( tid );
          /* Make any binding for LD_PRELOAD disappear, so that child
             processes don't get traced into. */
          if (!VG_(clo_trace_children)) {
@@ -1103,6 +1106,11 @@ void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid )
          if (VG_(clo_trace_syscalls))
             VG_(printf)("fork ()\n");
          KERNEL_DO_SYSCALL(tid,res);
+         if (res == 0) {
+            /* I am the child.  Nuke all other threads which I might
+               have inherited from my parent.  POSIX mandates this. */
+            VG_(nuke_all_threads_except)( tid );
+         }
          break;
 
       case __NR_fsync: /* syscall 118 */