]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
vg_signals.c: vg_oursignalhandler(): don't longjmp() on fatal signal if
authorJulian Seward <jseward@acm.org>
Sat, 13 Jul 2002 12:12:56 +0000 (12:12 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 13 Jul 2002 12:12:56 +0000 (12:12 +0000)
the scheduler's jmp_buf is not valid.  This might avoid at least some
of the following:
   vg_scheduler.c:479 (run_thread_for_a_while): Assertion `trc == 0'
   failed.

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

coregrind/vg_include.h
coregrind/vg_scheduler.c
coregrind/vg_signals.c
vg_include.h
vg_scheduler.c
vg_signals.c

index d489be3ebc179c151c42b636e1c4576b284785ba..40506c126b0dc2d8542ee6851ad6ade45bab3beb 100644 (file)
@@ -776,6 +776,10 @@ extern void VG_(pp_sched_status) ( void );
 
 /* vg_oursignalhandler() might longjmp().  Here's the jmp_buf. */
 extern jmp_buf VG_(scheduler_jmpbuf);
+/* This says whether scheduler_jmpbuf is actually valid.  Needed so
+   that our signal handler doesn't longjmp when the buffer isn't
+   actually valid. */
+extern Bool    VG_(scheduler_jmpbuf_valid);
 /* ... and if so, here's the signal which caused it to do so. */
 extern Int     VG_(longjmpd_on_signal);
 
index 6a99730bebf5c2b852f30b9550eb7a4dce8513bd..12024e0599b7e656cdb471b02237d62f0d61fd0b 100644 (file)
@@ -99,6 +99,10 @@ static Int vg_tid_currently_in_baseBlock = VG_INVALID_THREADID;
 
 /* vg_oursignalhandler() might longjmp().  Here's the jmp_buf. */
 jmp_buf VG_(scheduler_jmpbuf);
+/* This says whether scheduler_jmpbuf is actually valid.  Needed so
+   that our signal handler doesn't longjmp when the buffer isn't
+   actually valid. */
+Bool    VG_(scheduler_jmpbuf_valid) = False;
 /* ... and if so, here's the signal which caused it to do so. */
 Int     VG_(longjmpd_on_signal);
 
@@ -466,19 +470,26 @@ UInt run_thread_for_a_while ( ThreadId tid )
    vg_assert(VG_(is_valid_tid)(tid));
    vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
    vg_assert(VG_(bbs_to_go) > 0);
+   vg_assert(!VG_(scheduler_jmpbuf_valid));
 
    VGP_PUSHCC(VgpRun);
    VG_(load_thread_state) ( tid );
    if (__builtin_setjmp(VG_(scheduler_jmpbuf)) == 0) {
       /* try this ... */
+      VG_(scheduler_jmpbuf_valid) = True;
       trc = VG_(run_innerloop)();
+      VG_(scheduler_jmpbuf_valid) = False;
       /* We get here if the client didn't take a fault. */
    } else {
       /* We get here if the client took a fault, which caused our
          signal handler to longjmp. */
+      VG_(scheduler_jmpbuf_valid) = False;
       vg_assert(trc == 0);
       trc = VG_TRC_UNRESUMABLE_SIGNAL;
    }
+
+   vg_assert(!VG_(scheduler_jmpbuf_valid));
+
    VG_(save_thread_state) ( tid );
    VGP_POPCC;
    return trc;
@@ -596,6 +607,9 @@ void VG_(scheduler_init) ( void )
 
    /* So now ... */
    vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
+
+   /* Not running client code right now. */
+   VG_(scheduler_jmpbuf_valid) = False;
 }
 
 
index 3dce4d8decc27e19e469cc745be3cba34063e16e..f58ec11e960e803877778c55ddfab365ae810012 100644 (file)
@@ -1258,6 +1258,7 @@ Bool VG_(deliver_signals) ( void )
 static 
 void vg_oursignalhandler ( Int sigNo )
 {
+   static UInt   segv_warns = 0;
    ThreadId      tid;
    Int           dummy_local;
    Bool          sane;
@@ -1352,13 +1353,26 @@ void vg_oursignalhandler ( Int sigNo )
       signals. */
    VG_(restore_all_host_signals)( &saved_procmask );
 
-   if (sigNo == VKI_SIGSEGV || sigNo == VKI_SIGBUS 
-       || sigNo == VKI_SIGFPE || sigNo == VKI_SIGILL) {
+   if ( (sigNo == VKI_SIGSEGV || sigNo == VKI_SIGBUS 
+         || sigNo == VKI_SIGFPE || sigNo == VKI_SIGILL)
+        &&
+        VG_(scheduler_jmpbuf_valid)
+      ) {
       /* Can't continue; must longjmp back to the scheduler and thus
          enter the sighandler immediately. */
       VG_(longjmpd_on_signal) = sigNo;
       __builtin_longjmp(VG_(scheduler_jmpbuf),1);
    }
+
+   if (sigNo == VKI_SIGSEGV && !VG_(scheduler_jmpbuf_valid)) {
+      if (++segv_warns <= 3) {
+       VG_(message)(Vg_UserMsg, 
+           "Warning: SIGSEGV not in user code; either from syscall kill()" );
+       VG_(message)(Vg_UserMsg, 
+           "   or possible Valgrind bug.  "
+           "This message is only shown 3 times." );
+      }
+   }
 }
 
 
index d489be3ebc179c151c42b636e1c4576b284785ba..40506c126b0dc2d8542ee6851ad6ade45bab3beb 100644 (file)
@@ -776,6 +776,10 @@ extern void VG_(pp_sched_status) ( void );
 
 /* vg_oursignalhandler() might longjmp().  Here's the jmp_buf. */
 extern jmp_buf VG_(scheduler_jmpbuf);
+/* This says whether scheduler_jmpbuf is actually valid.  Needed so
+   that our signal handler doesn't longjmp when the buffer isn't
+   actually valid. */
+extern Bool    VG_(scheduler_jmpbuf_valid);
 /* ... and if so, here's the signal which caused it to do so. */
 extern Int     VG_(longjmpd_on_signal);
 
index 6a99730bebf5c2b852f30b9550eb7a4dce8513bd..12024e0599b7e656cdb471b02237d62f0d61fd0b 100644 (file)
@@ -99,6 +99,10 @@ static Int vg_tid_currently_in_baseBlock = VG_INVALID_THREADID;
 
 /* vg_oursignalhandler() might longjmp().  Here's the jmp_buf. */
 jmp_buf VG_(scheduler_jmpbuf);
+/* This says whether scheduler_jmpbuf is actually valid.  Needed so
+   that our signal handler doesn't longjmp when the buffer isn't
+   actually valid. */
+Bool    VG_(scheduler_jmpbuf_valid) = False;
 /* ... and if so, here's the signal which caused it to do so. */
 Int     VG_(longjmpd_on_signal);
 
@@ -466,19 +470,26 @@ UInt run_thread_for_a_while ( ThreadId tid )
    vg_assert(VG_(is_valid_tid)(tid));
    vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
    vg_assert(VG_(bbs_to_go) > 0);
+   vg_assert(!VG_(scheduler_jmpbuf_valid));
 
    VGP_PUSHCC(VgpRun);
    VG_(load_thread_state) ( tid );
    if (__builtin_setjmp(VG_(scheduler_jmpbuf)) == 0) {
       /* try this ... */
+      VG_(scheduler_jmpbuf_valid) = True;
       trc = VG_(run_innerloop)();
+      VG_(scheduler_jmpbuf_valid) = False;
       /* We get here if the client didn't take a fault. */
    } else {
       /* We get here if the client took a fault, which caused our
          signal handler to longjmp. */
+      VG_(scheduler_jmpbuf_valid) = False;
       vg_assert(trc == 0);
       trc = VG_TRC_UNRESUMABLE_SIGNAL;
    }
+
+   vg_assert(!VG_(scheduler_jmpbuf_valid));
+
    VG_(save_thread_state) ( tid );
    VGP_POPCC;
    return trc;
@@ -596,6 +607,9 @@ void VG_(scheduler_init) ( void )
 
    /* So now ... */
    vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
+
+   /* Not running client code right now. */
+   VG_(scheduler_jmpbuf_valid) = False;
 }
 
 
index 3dce4d8decc27e19e469cc745be3cba34063e16e..f58ec11e960e803877778c55ddfab365ae810012 100644 (file)
@@ -1258,6 +1258,7 @@ Bool VG_(deliver_signals) ( void )
 static 
 void vg_oursignalhandler ( Int sigNo )
 {
+   static UInt   segv_warns = 0;
    ThreadId      tid;
    Int           dummy_local;
    Bool          sane;
@@ -1352,13 +1353,26 @@ void vg_oursignalhandler ( Int sigNo )
       signals. */
    VG_(restore_all_host_signals)( &saved_procmask );
 
-   if (sigNo == VKI_SIGSEGV || sigNo == VKI_SIGBUS 
-       || sigNo == VKI_SIGFPE || sigNo == VKI_SIGILL) {
+   if ( (sigNo == VKI_SIGSEGV || sigNo == VKI_SIGBUS 
+         || sigNo == VKI_SIGFPE || sigNo == VKI_SIGILL)
+        &&
+        VG_(scheduler_jmpbuf_valid)
+      ) {
       /* Can't continue; must longjmp back to the scheduler and thus
          enter the sighandler immediately. */
       VG_(longjmpd_on_signal) = sigNo;
       __builtin_longjmp(VG_(scheduler_jmpbuf),1);
    }
+
+   if (sigNo == VKI_SIGSEGV && !VG_(scheduler_jmpbuf_valid)) {
+      if (++segv_warns <= 3) {
+       VG_(message)(Vg_UserMsg, 
+           "Warning: SIGSEGV not in user code; either from syscall kill()" );
+       VG_(message)(Vg_UserMsg, 
+           "   or possible Valgrind bug.  "
+           "This message is only shown 3 times." );
+      }
+   }
 }