|
From: <sv...@va...> - 2013-11-12 15:33:26
|
Author: weidendo
Date: Tue Nov 12 15:32:58 2013
New Revision: 13712
Log:
Fix bug 327238.
assertion failure in Callgrind: bbcc.c:585 (vgCallgrind_setup_bbcc):
Assertion 'passed <= last_bb->cjmp_count' failed
Background:
We want to detect the jump behavior of code, that is, the side exit
from a SB, as there can be many. For that, instrumented code writes
the exit number into a global variable (jmps_passed) before an eventual
exit.
With an exception happening in the first few instructions of an SB,
jmps_passed never was written, and still contained an old value. This
got saved/restored around the exception handler, and resulted in the
failed assertion.
Solution: always initialize jmps_passed to zero in setup_bbcc(), which
is called at the beginning of every SB.
Modified:
trunk/callgrind/bbcc.c
trunk/callgrind/global.h
trunk/callgrind/main.c
Modified: trunk/callgrind/bbcc.c
==============================================================================
--- trunk/callgrind/bbcc.c (original)
+++ trunk/callgrind/bbcc.c Tue Nov 12 15:32:58 2013
@@ -885,6 +885,10 @@
}
CLG_(current_state).bbcc = bbcc;
+ /* Even though this will be set in instrumented code directly before
+ * side exits, it needs to be set to 0 here in case an exception
+ * happens in first instructions of the BB */
+ CLG_(current_state).jmps_passed = 0;
// needed for log_* handlers called in this BB
CLG_(bb_base) = bb->obj->offset + bb->offset;
CLG_(cost_base) = bbcc->cost;
Modified: trunk/callgrind/global.h
==============================================================================
--- trunk/callgrind/global.h (original)
+++ trunk/callgrind/global.h Tue Nov 12 15:32:58 2013
@@ -523,7 +523,8 @@
Bool collect;
Context* cxt;
- Int jmps_passed; /* number of conditional jumps passed in last BB */
+ /* number of conditional jumps passed in last BB */
+ Int jmps_passed;
BBCC* bbcc; /* last BB executed */
BBCC* nonskipped;
Modified: trunk/callgrind/main.c
==============================================================================
--- trunk/callgrind/main.c (original)
+++ trunk/callgrind/main.c Tue Nov 12 15:32:58 2013
@@ -1243,9 +1243,10 @@
/* Update global variable jmps_passed before the jump
* A correction is needed if VEX inverted the last jump condition
*/
+ UInt val = inverted ? cJumps+1 : cJumps;
addConstMemStoreStmt( clgs.sbOut,
(UWord) &CLG_(current_state).jmps_passed,
- inverted ? cJumps+1 : cJumps, hWordTy);
+ val, hWordTy);
cJumps++;
break;
@@ -1289,10 +1290,12 @@
/* At the end of the bb. Flush outstandings. */
flushEvents( &clgs );
- /* Always update global variable jmps_passed at end of bb.
+ /* Update global variable jmps_passed at end of SB.
+ * As CLG_(current_state).jmps_passed is reset to 0 in setup_bbcc,
+ * this can be omitted if there is no conditional jump in this SB.
* A correction is needed if VEX inverted the last jump condition
*/
- {
+ if (cJumps>0) {
UInt jmps_passed = cJumps;
if (clgs.bb->cjmp_inverted) jmps_passed--;
addConstMemStoreStmt( clgs.sbOut,
|