From 8e9e99f943f15fee50d5971b6c9665ad79b51ba4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 1 Aug 2004 22:59:18 +0000 Subject: [PATCH] Replaced three global variables in vg_include.h with a single global function; much neater. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2542 --- coregrind/vg_include.h | 11 ++--------- coregrind/vg_scheduler.c | 36 ++++++++++++++++++++++++------------ coregrind/vg_signals.c | 24 +++++------------------- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 29ac330256..2aeaa451a4 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -983,15 +983,8 @@ extern void VG_(scheduler_init) ( void ); 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); - +// Longjmp back to the scheduler and thus enter the sighandler immediately. +extern void VG_(resume_scheduler) ( Int sigNo, vki_ksiginfo_t *info ); /* The red-zone size which we put at the bottom (highest address) of thread stacks, for paranoia reasons. This can be arbitrary, and diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index e1e772324c..cca2220494 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -88,13 +88,13 @@ static ThreadId vg_tid_currently_in_baseBlock = VG_INVALID_THREADID; static ThreadId vg_tid_last_in_baseBlock = VG_INVALID_THREADID; /* vg_oursignalhandler() might longjmp(). Here's the jmp_buf. */ -jmp_buf VG_(scheduler_jmpbuf); +jmp_buf 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; +Bool scheduler_jmpbuf_valid = False; /* ... and if so, here's the signal which caused it to do so. */ -Int VG_(longjmpd_on_signal); +Int longjmpd_on_signal; /* If the current thread gets a syncronous unresumable signal, then its details are placed here by the signal handler, to be passed to the applications signal handler later on. */ @@ -523,6 +523,18 @@ void VG_(save_thread_state) ( ThreadId tid ) } +void VG_(resume_scheduler)(Int sigNo, vki_ksiginfo_t *info) +{ + if (scheduler_jmpbuf_valid) { + /* Can't continue; must longjmp back to the scheduler and thus + enter the sighandler immediately. */ + VG_(memcpy)(&VG_(unresumable_siginfo), info, sizeof(vki_ksiginfo_t)); + + longjmpd_on_signal = sigNo; + __builtin_longjmp(scheduler_jmpbuf,1); + } +} + /* Run the thread tid for a while, and return a VG_TRC_* value to the scheduler indicating what happened. */ static @@ -531,7 +543,7 @@ UInt run_thread_for_a_while ( ThreadId tid ) volatile UInt trc = 0; vg_assert(VG_(is_valid_tid)(tid)); vg_assert(VG_(threads)[tid].status == VgTs_Runnable); - vg_assert(!VG_(scheduler_jmpbuf_valid)); + vg_assert(!scheduler_jmpbuf_valid); VGP_PUSHCC(VgpRun); VG_(load_thread_state) ( tid ); @@ -539,21 +551,21 @@ UInt run_thread_for_a_while ( ThreadId tid ) /* there should be no undealt-with signals */ vg_assert(VG_(unresumable_siginfo).si_signo == 0); - if (__builtin_setjmp(VG_(scheduler_jmpbuf)) == 0) { + if (__builtin_setjmp(scheduler_jmpbuf) == 0) { /* try this ... */ - VG_(scheduler_jmpbuf_valid) = True; + scheduler_jmpbuf_valid = True; trc = VG_(run_innerloop)(); - VG_(scheduler_jmpbuf_valid) = False; + 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; + scheduler_jmpbuf_valid = False; vg_assert(trc == 0); trc = VG_TRC_UNRESUMABLE_SIGNAL; } - vg_assert(!VG_(scheduler_jmpbuf_valid)); + vg_assert(!scheduler_jmpbuf_valid); VG_(save_thread_state) ( tid ); VGP_POPCC(VgpRun); @@ -643,7 +655,7 @@ void VG_(scheduler_init) ( void ) vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID); /* Not running client code right now. */ - VG_(scheduler_jmpbuf_valid) = False; + scheduler_jmpbuf_valid = False; /* Proxy for main thread */ VG_(proxy_create)(tid_main); @@ -1234,10 +1246,10 @@ VgSchedReturnCode VG_(scheduler) ( Int* exitcode ) VG_(unresumable_siginfo).si_signo == VKI_SIGBUS || VG_(unresumable_siginfo).si_signo == VKI_SIGILL || VG_(unresumable_siginfo).si_signo == VKI_SIGFPE); - vg_assert(VG_(longjmpd_on_signal) == VG_(unresumable_siginfo).si_signo); + vg_assert(longjmpd_on_signal == VG_(unresumable_siginfo).si_signo); /* make sure we've unblocked the signals which the handler blocked */ - VG_(unblock_host_signal)(VG_(longjmpd_on_signal)); + VG_(unblock_host_signal)(longjmpd_on_signal); VG_(deliver_signal)(tid, &VG_(unresumable_siginfo), False); VG_(unresumable_siginfo).si_signo = 0; /* done */ diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index 0a4f6e4a8d..d2f88d0c9a 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -64,8 +64,7 @@ with shared signal state (Linux 2.5+, RedHat's 2.4), then these are the only signals it needs to handle. - If we get a synchronous signal, the details are placed into - VG_(unresumable_siginfo) and we longjmp back into the scheduler, + If we get a synchronous signal, we longjmp back into the scheduler, since we can't resume executing the client code. The scheduler immediately starts signal delivery to the thread which generated the signal. @@ -100,7 +99,6 @@ static void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki static void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * ); static void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * ); static void proxy_sigvg_handler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * ); -static void resume_scheduler(Int signo, vki_ksiginfo_t *info); static Bool is_correct_sigmask(void); static const Char *signame(Int sigNo); @@ -1834,7 +1832,7 @@ void VG_(synth_fault_perms)(ThreadId tid, Addr addr) info.si_code = 2; info._sifields._sigfault._addr = (void*)addr; - resume_scheduler(VKI_SIGSEGV, &info); + VG_(resume_scheduler)(VKI_SIGSEGV, &info); VG_(deliver_signal)(tid, &info, False); } @@ -1850,7 +1848,7 @@ void VG_(synth_fault_mapping)(ThreadId tid, Addr addr) info.si_code = 1; info._sifields._sigfault._addr = (void*)addr; - resume_scheduler(VKI_SIGSEGV, &info); + VG_(resume_scheduler)(VKI_SIGSEGV, &info); VG_(deliver_signal)(tid, &info, False); } @@ -1865,7 +1863,7 @@ void VG_(synth_fault)(ThreadId tid) info.si_code = 0x80; info._sifields._sigfault._addr = (void*)0; - resume_scheduler(VKI_SIGSEGV, &info); + VG_(resume_scheduler)(VKI_SIGSEGV, &info); VG_(deliver_signal)(tid, &info, False); } @@ -2024,18 +2022,6 @@ void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_uconte VG_(proxy_handlesig)(info, &uc->uc_mcontext); } -static void resume_scheduler(Int sigNo, vki_ksiginfo_t *info) -{ - if (VG_(scheduler_jmpbuf_valid)) { - /* Can't continue; must longjmp back to the scheduler and thus - enter the sighandler immediately. */ - VG_(memcpy)(&VG_(unresumable_siginfo), info, sizeof(vki_ksiginfo_t)); - - VG_(longjmpd_on_signal) = sigNo; - __builtin_longjmp(VG_(scheduler_jmpbuf),1); - } -} - /* Recieve a sync signal from the host. @@ -2176,7 +2162,7 @@ void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontex /* Can't continue; must longjmp back to the scheduler and thus enter the sighandler immediately. */ - resume_scheduler(sigNo, info); + VG_(resume_scheduler)(sigNo, info); if (info->si_code <= VKI_SI_USER) { /* -- 2.47.2