/* 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);
/* 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);
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;
/* So now ... */
vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
+
+ /* Not running client code right now. */
+ VG_(scheduler_jmpbuf_valid) = False;
}
static
void vg_oursignalhandler ( Int sigNo )
{
+ static UInt segv_warns = 0;
ThreadId tid;
Int dummy_local;
Bool sane;
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." );
+ }
+ }
}
/* 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);
/* 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);
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;
/* So now ... */
vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
+
+ /* Not running client code right now. */
+ VG_(scheduler_jmpbuf_valid) = False;
}
static
void vg_oursignalhandler ( Int sigNo )
{
+ static UInt segv_warns = 0;
ThreadId tid;
Int dummy_local;
Bool sane;
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." );
+ }
+ }
}