From: Josef Weidendorfer Date: Wed, 1 Jul 2009 23:56:23 +0000 (+0000) Subject: Fix handling of multiple signal deliveries in a row X-Git-Tag: svn/VALGRIND_3_5_0~447 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8138daf9d7aee72aa5609c94267ca617346dd745;p=thirdparty%2Fvalgrind.git Fix handling of multiple signal deliveries in a row This fixes bug 136154. Background: The function stack - CLG_(current_fn_stack) - is a stack of pointers to the fn_node structs of the currently active functions. This stack is used for determining current context from call chain to current function, and modified on entering (via push_cxt) and leaving a function. Entering a signal handler will push a 0 to the function stack to make the context only dependend on the call chain inside of the signal handler. Thus, delivering two signals in a row should push two times a 0 value onto the function stack. However, the second 0-push was incorrectly suppressed, leading to a failed assertion when returning from the 2nd signal handler. This also fixes a bug with incorrectly zeroing global cost counters when changing the execution context, introduced with r10386. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10399 --- diff --git a/callgrind/context.c b/callgrind/context.c index 9abe6d1519..eb478fd5df 100644 --- a/callgrind/context.c +++ b/callgrind/context.c @@ -276,7 +276,7 @@ Context* CLG_(get_cxt)(fn_node** fn) /** * Change execution context by calling a new function from current context - * + * Pushing 0x0 specifies a marker for a signal handler entry */ void CLG_(push_cxt)(fn_node* fn) { @@ -294,7 +294,7 @@ void CLG_(push_cxt)(fn_node* fn) cs->entry[cs->sp].cxt = CLG_(current_state).cxt; cs->entry[cs->sp].fn_sp = CLG_(current_fn_stack).top - CLG_(current_fn_stack).bottom; - if (*(CLG_(current_fn_stack).top) == fn) return; + if (fn && (*(CLG_(current_fn_stack).top) == fn)) return; if (fn && (fn->group>0) && ((*(CLG_(current_fn_stack).top))->group == fn->group)) return; @@ -318,11 +318,10 @@ void CLG_(push_cxt)(fn_node* fn) CLG_(current_fn_stack).size = new_size; } - if (*(CLG_(current_fn_stack).top) == 0) { + if (fn && (*(CLG_(current_fn_stack).top) == 0)) { UInt *pactive; /* this is first function: increment its active count */ - CLG_ASSERT(fn != 0); pactive = CLG_(get_fn_entry)(fn->number); (*pactive)++; } diff --git a/callgrind/threads.c b/callgrind/threads.c index d08bb7234a..196fb875fa 100644 --- a/callgrind/threads.c +++ b/callgrind/threads.c @@ -208,17 +208,16 @@ void CLG_(pre_signal)(ThreadId tid, Int sigNum, Bool alt_stack) /* save current execution state */ exec_state_save(); - /* setup current state for a spontaneous call */ - CLG_(init_exec_state)( &CLG_(current_state) ); - CLG_(push_cxt)(0); - /* setup new cxtinfo struct for this signal handler */ es = push_exec_state(sigNum); - CLG_(init_cost)( CLG_(sets).full, es->cost); + // because of this, below call to init_exec_state will zero es->cost CLG_(current_state).cost = es->cost; es->call_stack_bottom = CLG_(current_call_stack).sp; + /* setup current state for a spontaneous call */ + CLG_(init_exec_state)( &CLG_(current_state) ); CLG_(current_state).sig = sigNum; + CLG_(push_cxt)(0); } /* Run post-signal if the stackpointer for call stack is at @@ -418,6 +417,7 @@ exec_state* exec_state_save(void) es->jmps_passed = CLG_(current_state).jmps_passed; es->bbcc = CLG_(current_state).bbcc; es->nonskipped = CLG_(current_state).nonskipped; + CLG_ASSERT(es->cost == CLG_(current_state).cost); CLG_DEBUGIF(1) { CLG_DEBUG(1, " cxtinfo_save(sig %d): collect %s, jmps_passed %d\n",