|
From: <sv...@va...> - 2009-07-01 23:56:29
|
Author: weidendo
Date: 2009-07-02 00:56:23 +0100 (Thu, 02 Jul 2009)
New Revision: 10399
Log:
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.
Modified:
trunk/callgrind/context.c
trunk/callgrind/threads.c
Modified: trunk/callgrind/context.c
===================================================================
--- trunk/callgrind/context.c 2009-07-01 18:46:27 UTC (rev 10398)
+++ trunk/callgrind/context.c 2009-07-01 23:56:23 UTC (rev 10399)
@@ -276,7 +276,7 @@
/**
* 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 @@
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 @@
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)++;
}
Modified: trunk/callgrind/threads.c
===================================================================
--- trunk/callgrind/threads.c 2009-07-01 18:46:27 UTC (rev 10398)
+++ trunk/callgrind/threads.c 2009-07-01 23:56:23 UTC (rev 10399)
@@ -208,17 +208,16 @@
/* 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 @@
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",
|