Moved more stuff out of core_os.c into better places.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3896
This commit is contained in:
Nicholas Nethercote 2005-06-12 04:19:17 +00:00
parent c50197ce86
commit 2e653771e7
5 changed files with 86 additions and 90 deletions

View File

@ -163,21 +163,12 @@ extern VgSchedReturnCode VGO_(thread_wrapper)(Word /*ThreadId*/ tid);
// wait until all other threads are dead
extern void VGA_(reap_threads)(ThreadId self);
// handle an arch-specific client request
extern Bool VGA_(client_request)(ThreadId tid, UWord *args);
// For attaching the debugger
extern Int VGA_(ptrace_setregs_from_tst) ( Int pid, ThreadArchState* arch );
// Used by leakcheck
extern void VGA_(mark_from_registers)(ThreadId tid, void (*marker)(Addr));
// Set up the libc freeres wrapper
extern void VGA_(intercept_libc_freeres_wrapper)(Addr);
// Clean up the client by calling before the final reports
extern void VGA_(final_tidyup)(ThreadId tid);
/* ---------------------------------------------------------------------
Finally - autoconf-generated settings
------------------------------------------------------------------ */

View File

@ -103,84 +103,6 @@ void VGA_(reap_threads)(ThreadId self)
vg_assert(i_am_the_only_thread());
}
/* The we need to know the address of it so it can be
called at program exit. */
static Addr __libc_freeres_wrapper;
void VGA_(intercept_libc_freeres_wrapper)(Addr addr)
{
__libc_freeres_wrapper = addr;
}
/* Final clean-up before terminating the process.
Clean up the client by calling __libc_freeres() (if requested) */
void VGA_(final_tidyup)(ThreadId tid)
{
vg_assert(VG_(is_running_thread)(tid));
if (!VG_(needs).libc_freeres ||
!VG_(clo_run_libc_freeres) ||
__libc_freeres_wrapper == 0)
return; /* can't/won't do it */
if (VG_(clo_verbosity) > 2 ||
VG_(clo_trace_syscalls) ||
VG_(clo_trace_sched))
VG_(message)(Vg_DebugMsg,
"Caught __NR_exit; running __libc_freeres()");
/* point thread context to point to libc_freeres_wrapper */
INSTR_PTR(VG_(threads)[tid].arch) = __libc_freeres_wrapper;
// XXX should we use a special stack?
/* Block all blockable signals by copying the real block state into
the thread's block state*/
VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
/* and restore handlers to default */
VG_(set_default_handler)(VKI_SIGSEGV);
VG_(set_default_handler)(VKI_SIGBUS);
VG_(set_default_handler)(VKI_SIGILL);
VG_(set_default_handler)(VKI_SIGFPE);
// We were exiting, so assert that...
vg_assert(VG_(is_exiting)(tid));
// ...but now we're not again
VG_(threads)[tid].exitreason = VgSrc_None;
// run until client thread exits - ideally with LIBC_FREERES_DONE,
// but exit/exitgroup/signal will do
VG_(scheduler)(tid);
vg_assert(VG_(is_exiting)(tid));
}
// Arch-specific client requests
Bool VGA_(client_request)(ThreadId tid, UWord *args)
{
Bool handled = True;
vg_assert(VG_(is_running_thread)(tid));
switch(args[0]) {
case VG_USERREQ__LIBC_FREERES_DONE:
/* This is equivalent to an exit() syscall, but we don't set the
exitcode (since it might already be set) */
if (0 || VG_(clo_trace_syscalls) || VG_(clo_trace_sched))
VG_(message)(Vg_DebugMsg,
"__libc_freeres() done; really quitting!");
VG_(threads)[tid].exitreason = VgSrc_ExitSyscall;
break;
default:
handled = False;
break;
}
return handled;
}
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/

View File

@ -2802,6 +2802,61 @@ int main(int argc, char **argv, char **envp)
}
/* The we need to know the address of it so it can be
called at program exit. */
static Addr __libc_freeres_wrapper;
void VGA_(intercept_libc_freeres_wrapper)(Addr addr)
{
__libc_freeres_wrapper = addr;
}
/* Final clean-up before terminating the process.
Clean up the client by calling __libc_freeres() (if requested)
This is Linux-specific?
*/
static void final_tidyup(ThreadId tid)
{
vg_assert(VG_(is_running_thread)(tid));
if (!VG_(needs).libc_freeres ||
!VG_(clo_run_libc_freeres) ||
__libc_freeres_wrapper == 0)
return; /* can't/won't do it */
if (VG_(clo_verbosity) > 2 ||
VG_(clo_trace_syscalls) ||
VG_(clo_trace_sched))
VG_(message)(Vg_DebugMsg,
"Caught __NR_exit; running __libc_freeres()");
/* point thread context to point to libc_freeres_wrapper */
INSTR_PTR(VG_(threads)[tid].arch) = __libc_freeres_wrapper;
// XXX should we use a special stack?
/* Block all blockable signals by copying the real block state into
the thread's block state*/
VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
/* and restore handlers to default */
VG_(set_default_handler)(VKI_SIGSEGV);
VG_(set_default_handler)(VKI_SIGBUS);
VG_(set_default_handler)(VKI_SIGILL);
VG_(set_default_handler)(VKI_SIGFPE);
// We were exiting, so assert that...
vg_assert(VG_(is_exiting)(tid));
// ...but now we're not again
VG_(threads)[tid].exitreason = VgSrc_None;
// run until client thread exits - ideally with LIBC_FREERES_DONE,
// but exit/exitgroup/signal will do
VG_(scheduler)(tid);
vg_assert(VG_(is_exiting)(tid));
}
/* Do everything which needs doing when the last thread exits */
void VG_(shutdown_actions_NORETURN) ( ThreadId tid,
VgSchedReturnCode tids_schedretcode )
@ -2817,7 +2872,7 @@ void VG_(shutdown_actions_NORETURN) ( ThreadId tid,
VG_(clo_model_pthreads) = False;
// Clean the client up before the final report
VGA_(final_tidyup)(tid);
final_tidyup(tid);
// OK, done
VG_(exit_thread)(tid);

View File

@ -983,6 +983,32 @@ void VG_(get_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size,
Handle client requests.
------------------------------------------------------------------ */
// OS-specific(?) client requests
static Bool os_client_request(ThreadId tid, UWord *args)
{
Bool handled = True;
vg_assert(VG_(is_running_thread)(tid));
switch(args[0]) {
case VG_USERREQ__LIBC_FREERES_DONE:
/* This is equivalent to an exit() syscall, but we don't set the
exitcode (since it might already be set) */
if (0 || VG_(clo_trace_syscalls) || VG_(clo_trace_sched))
VG_(message)(Vg_DebugMsg,
"__libc_freeres() done; really quitting!");
VG_(threads)[tid].exitreason = VgSrc_ExitSyscall;
break;
default:
handled = False;
break;
}
return handled;
}
/* Do a client request for the thread tid. After the request, tid may
or may not still be runnable; if not, the scheduler will have to
choose a new thread to run.
@ -1109,8 +1135,8 @@ void do_client_request ( ThreadId tid )
break;
default:
if (VGA_(client_request)(tid, arg)) {
/* architecture handled the client request */
if (os_client_request(tid, arg)) {
// do nothing, os_client_request() handled it
} else if (VG_(needs).client_requests) {
UWord ret;

View File

@ -54,6 +54,8 @@ extern void VG_(start_debugger) ( ThreadId tid );
/* 64-bit counter for the number of basic blocks done. */
extern ULong VG_(bbs_done);
// Set up the libc freeres wrapper (XXX: currently unused -- ?!)
extern void VGA_(intercept_libc_freeres_wrapper)(Addr);
#endif // __PUB_CORE_MAIN_H