mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-06 11:41:34 +00:00
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:
parent
c50197ce86
commit
2e653771e7
@ -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
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
@ -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 ---*/
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user