|
From: <sv...@va...> - 2007-10-28 14:54:47
|
Author: sewardj
Date: 2007-10-28 14:54:49 +0000 (Sun, 28 Oct 2007)
New Revision: 7047
Log:
Add new flags --trace-addr and --trace-level, which cause all state
changes for a given address to be logged. Intended to help track down
the root causes of races.
At --trace-level=2, a complete stack trace is printed every time the
location specified with --trace-addr changes state.
At --trace-level=1 (the default) just a 1-line summary for each state
change is printed.
Also a bit of comment-tidying and variable renaming.
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-28 14:51:23 UTC (rev 7046)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-28 14:54:49 UTC (rev 7047)
@@ -47,6 +47,7 @@
#include "pub_tool_machine.h"
#include "pub_tool_options.h"
#include "pub_tool_xarray.h"
+#include "pub_tool_stacktrace.h"
#include "thrcheck.h"
@@ -126,6 +127,12 @@
(regtesting) this is sometimes important. */
static Bool clo_cmp_race_err_addrs = False;
+/* Tracing memory accesses, so we can see what's going on.
+ clo_trace_addr is the address to monitor. clo_trace_level = 0 for
+ no tracing, 1 for summary, 2 for detailed. */
+static Addr clo_trace_addr = 0;
+static Int clo_trace_level = 0;
+
// FIXME: when a SecMap is completely set via and address range
// setting operation to a non-ShR/M state, clear its .mbHasShared
// bit
@@ -675,9 +682,9 @@
/* EXPOSITION only */
/* We need to keep recording snapshots of where the lock was
acquired, up till the point that the lock gets incorporated into
- LAOG. Before that point, .first_locked_laog is NULL. When the
- lock is incorporated into LAOG, .first_locked is copied into
- .first_locked_laog and we stop snapshotting it after that.
+ LAOG. Before that point, .acquired_at_laog is NULL. When the
+ lock is incorporated into LAOG, .acquired_at is copied into
+ .acquired_at_laog and we stop snapshotting it after that.
This is so as to produce better lock-order error messages. */
if (lk->acquired_at_laog == NULL) {
ThreadId tid = map_threads_maybe_reverse_lookup_SLOW(thr);
@@ -734,9 +741,9 @@
/* EXPOSITION only */
/* We need to keep recording snapshots of where the lock was
acquired, up till the point that the lock gets incorporated into
- LAOG. Before that point, .first_locked_laog is NULL. When the
- lock is incorporated into LAOG, .first_locked is copied into
- .first_locked_laog and we stop snapshotting it after that.
+ LAOG. Before that point, .acquired_at_laog is NULL. When the
+ lock is incorporated into LAOG, .acquired_at is copied into
+ .acquired_at_laog and we stop snapshotting it after that.
This is so as to produce better lock-order error messages. */
if (lk->acquired_at_laog == NULL) {
ThreadId tid = map_threads_maybe_reverse_lookup_SLOW(thr);
@@ -969,8 +976,12 @@
/*--- Print out the primary data structures ---*/
/*----------------------------------------------------------------*/
-static void get_ZF_by_index ( /*OUT*/CacheLineZ** zp, /*OUT*/CacheLineF** fp,
- SecMap* sm, Int zix ); /* fwds */
+static WordSetID del_BHL ( WordSetID lockset ); /* fwds */
+static
+void get_ZF_by_index ( /*OUT*/CacheLineZ** zp, /*OUT*/CacheLineF** fp,
+ SecMap* sm, Int zix ); /* fwds */
+static
+Segment* map_segments_maybe_lookup ( SegmentID segid ); /* fwds */
#define PP_THREADS (1<<1)
#define PP_LOCKS (1<<2)
@@ -1190,6 +1201,49 @@
}
}
+static
+void show_shadow_w32_for_user ( /*OUT*/Char* buf, Int nBuf, UInt w32 )
+{
+ tl_assert(nBuf-1 >= 99);
+ VG_(memset)(buf, 0, nBuf);
+ if (is_SHVAL_ShM(w32)) {
+ WordSetID tset = un_SHVAL_ShM_tset(w32);
+ WordSetID lset = del_BHL( un_SHVAL_ShM_lset(w32) );
+ VG_(sprintf)(buf, "ShMod(#Tset=%d,#Lset=%d)",
+ TC_(cardinalityWS)(univ_tsets, tset),
+ TC_(cardinalityWS)(univ_lsets, lset));
+ }
+ else
+ if (is_SHVAL_ShR(w32)) {
+ WordSetID tset = un_SHVAL_ShR_tset(w32);
+ WordSetID lset = del_BHL( un_SHVAL_ShR_lset(w32) );
+ VG_(sprintf)(buf, "ShRO(#Tset=%d,#Lset=%d)",
+ TC_(cardinalityWS)(univ_tsets, tset),
+ TC_(cardinalityWS)(univ_lsets, lset));
+ }
+ else
+ if (is_SHVAL_Excl(w32)) {
+ SegmentID segid = un_SHVAL_Excl(w32);
+ Segment* mb_seg = map_segments_maybe_lookup(segid);
+ if (mb_seg && mb_seg->thr && is_sane_Thread(mb_seg->thr)) {
+ VG_(sprintf)(buf, "Exclusive(thr#%d)", mb_seg->thr->errmsg_index);
+ } else {
+ VG_(sprintf)(buf, "Exclusive(segid=%u)", un_SHVAL_Excl(w32));
+ }
+ }
+ else
+ if (is_SHVAL_New(w32)) {
+ VG_(sprintf)(buf, "%s", "New");
+ }
+ else
+ if (is_SHVAL_NoAccess(w32)) {
+ VG_(sprintf)(buf, "%s", "NoAccess");
+ }
+ else {
+ VG_(sprintf)(buf, "Invalid-shadow-word(%u)", w32);
+ }
+}
+
static void pp_SecMap_shared ( Int d, SecMap* sm, Addr ga )
{
Int i;
@@ -2668,26 +2722,26 @@
/*--- the core memory state machine (msm__* functions) ---*/
/*----------------------------------------------------------------*/
-static UWord stats__msm_r32_Excl_nochange = 0;
-static UWord stats__msm_r32_Excl_transfer = 0;
-static UWord stats__msm_r32_Excl_to_ShR = 0;
-static UWord stats__msm_r32_ShR_to_ShR = 0;
-static UWord stats__msm_r32_ShM_to_ShM = 0;
-static UWord stats__msm_r32_New_to_Excl = 0;
-static UWord stats__msm_r32_NoAccess = 0;
+static UWord stats__msm_read_Excl_nochange = 0;
+static UWord stats__msm_read_Excl_transfer = 0;
+static UWord stats__msm_read_Excl_to_ShR = 0;
+static UWord stats__msm_read_ShR_to_ShR = 0;
+static UWord stats__msm_read_ShM_to_ShM = 0;
+static UWord stats__msm_read_New_to_Excl = 0;
+static UWord stats__msm_read_NoAccess = 0;
-static UWord stats__msm_w32_Excl_nochange = 0;
-static UWord stats__msm_w32_Excl_transfer = 0;
-static UWord stats__msm_w32_Excl_to_ShM = 0;
-static UWord stats__msm_w32_ShR_to_ShM = 0;
-static UWord stats__msm_w32_ShM_to_ShM = 0;
-static UWord stats__msm_w32_New_to_Excl = 0;
-static UWord stats__msm_w32_NoAccess = 0;
+static UWord stats__msm_write_Excl_nochange = 0;
+static UWord stats__msm_write_Excl_transfer = 0;
+static UWord stats__msm_write_Excl_to_ShM = 0;
+static UWord stats__msm_write_ShR_to_ShM = 0;
+static UWord stats__msm_write_ShM_to_ShM = 0;
+static UWord stats__msm_write_New_to_Excl = 0;
+static UWord stats__msm_write_NoAccess = 0;
/* fwds */
static void record_error_Race ( Thread* thr,
Addr data_addr, Bool isWrite, Int szB,
- UInt old_w32, UInt new_w32,
+ UInt old_sv, UInt new_sv,
ExeContext* mb_lastlock );
static void record_error_FreeMemLock ( Thread* thr, Lock* lk );
@@ -2700,12 +2754,16 @@
ExeContext*, ExeContext* );
static void record_error_Misc ( Thread*, HChar* );
+static void announce_one_thread ( Thread* thr ); /* fwds */
-static WordSetID add_BHL ( WordSetID lockset )
-{
+static WordSetID add_BHL ( WordSetID lockset ) {
return TC_(addToWS)( univ_lsets, lockset, (Word)__bus_lock_Lock );
}
+static WordSetID del_BHL ( WordSetID lockset ) {
+ return TC_(delFromWS)( univ_lsets, lockset, (Word)__bus_lock_Lock );
+}
+
/* Last-lock-lossage records. This mechanism exists to help explain
to programmers why we are complaining about a race. The idea is to
monitor all lockset transitions. When a previously nonempty
@@ -2761,7 +2819,7 @@
/* This is slow, but at least it's simple. The bus hardware lock
just confuses the logic, so remove it from the locksets we're
considering before doing anything else. */
- lset_new = TC_(delFromWS)( univ_lsets, lset_new, (Word)__bus_lock_Lock );
+ lset_new = del_BHL( lset_new );
if (!TC_(isEmptyWS)( univ_lsets, lset_new )) {
/* The post-transition lock set is not empty. So we are not
@@ -2774,7 +2832,7 @@
card_new = TC_(cardinalityWS)( univ_lsets, lset_new );
tl_assert(card_new == 0);
- lset_old = TC_(delFromWS)( univ_lsets, lset_old, (Word)__bus_lock_Lock );
+ lset_old = del_BHL( lset_old );
card_old = TC_(cardinalityWS)( univ_lsets, lset_old );
if (0) VG_(printf)(" X2: %d (card %d) -> %d (card %d)\n",
@@ -2823,6 +2881,68 @@
}
+static void msm__show_state_change ( Thread* thr_acc, Addr a, Int szB,
+ Char howC,
+ UInt sv_old, UInt sv_new )
+{
+ ThreadId tid;
+ UChar txt_old[100], txt_new[100];
+ Char* how = "";
+ tl_assert(is_sane_Thread(thr_acc));
+ tl_assert(clo_trace_level == 1 || clo_trace_level == 2);
+ switch (howC) {
+ case 'r': how = "rd"; break;
+ case 'w': how = "wr"; break;
+ case 'p': how = "pa"; break;
+ default: tl_assert(0);
+ }
+ show_shadow_w32_for_user(txt_old, sizeof(txt_old), sv_old);
+ show_shadow_w32_for_user(txt_new, sizeof(txt_new), sv_new);
+ txt_old[sizeof(txt_old)-1] = 0;
+ txt_new[sizeof(txt_new)-1] = 0;
+ if (clo_trace_level == 2) {
+ /* show everything */
+ announce_one_thread( thr_acc );
+ VG_(message)(Vg_UserMsg,
+ "TRACE: %p %s %d thr#%d :: %s --> %s",
+ a, how, szB, thr_acc->errmsg_index, txt_old, txt_new );
+ tid = map_threads_maybe_reverse_lookup_SLOW(thr_acc);
+ if (tid != VG_INVALID_THREADID) {
+ VG_(get_and_pp_StackTrace)( tid, 8 );
+ }
+ VG_(message)(Vg_UserMsg, "");
+ } else {
+ /* Just print one line */
+ VG_(message)(Vg_UserMsg,
+ "TRACE: %p %s %d thr#%d :: %22s --> %22s",
+ a, how, szB, thr_acc->errmsg_index, txt_old, txt_new );
+ }
+}
+
+
+/* Here are some MSM stats from startup/shutdown of OpenOffice.
+
+ msm: 489,734,723 80,278,862 rd/wr_Excl_nochange
+ msm: 3,171,542 93,738 rd/wr_Excl_transfer
+ msm: 45,036 167 rd/wr_Excl_to_ShR/ShM
+ msm: 13,352,594 285 rd/wr_ShR_to_ShR/ShM
+ msm: 1,125,879 815,779 rd/wr_ShM_to_ShM
+ msm: 7,561,842 250,629,935 rd/wr_New_to_Excl
+ msm: 17,778 0 rd/wr_NoAccess
+
+ This says how the clauses should be ordered for greatest speed:
+
+ * the vast majority of memory reads (490 million out of a total of
+ 515 million) are of memory in an exclusive state, and the state
+ is unchanged. All other read accesses are insignificant by
+ comparison.
+
+ * 75% (251 million out of a total of 332 million) writes are 'first
+ time' writes, which take New memory into exclusive ownership.
+ Almost all the rest (80 million) are accesses to exclusive state,
+ which remains unchanged. All other write accesses are
+ insignificant. */
+
/* The core MSM. If 'wold' is the old 32-bit shadow word for a
location, return the new shadow word that would result for a read
of the location, and report any errors necessary on the way. This
@@ -2832,12 +2952,14 @@
static
UInt msm__handle_read ( Thread* thr_acc, Addr a, UInt wold, Int szB )
{
+ UInt wnew = SHVAL_Invalid;
+
tl_assert(is_sane_Thread(thr_acc));
if (0) VG_(printf)("read thr=%p %p\n", thr_acc, a);
/* Exclusive */
- if (is_SHVAL_Excl(wold)) {
+ if (LIKELY(is_SHVAL_Excl(wold))) {
/* read Excl(segid)
| segid_old == segid-of-thread
-> no change
@@ -2848,20 +2970,19 @@
*/
SegmentID segid_old = un_SHVAL_Excl(wold);
tl_assert(is_sane_SegmentID(segid_old));
- if (segid_old == thr_acc->csegid) {
+ if (LIKELY(segid_old == thr_acc->csegid)) {
/* no change */
- stats__msm_r32_Excl_nochange++;
- return wold;
+ stats__msm_read_Excl_nochange++;
+ /*NOCHANGE*/return wold;
}
if (happens_before(segid_old, thr_acc->csegid)) {
/* -> Excl(segid-of-this-thread) */
- UInt wnew = mk_SHVAL_Excl(thr_acc->csegid);
- stats__msm_r32_Excl_transfer++;
- return wnew;
+ wnew = mk_SHVAL_Excl(thr_acc->csegid);
+ stats__msm_read_Excl_transfer++;
+ goto changed;
}
/* else */ {
/* Enter the shared-readonly (ShR) state. */
- UInt wnew;
WordSetID tset, lset;
/* This location has been accessed by precisely two threads.
Make an appropriate tset. */
@@ -2872,8 +2993,8 @@
tset = TC_(doubletonWS)( univ_tsets, (Word)thr_old, (Word)thr_acc );
lset = add_BHL( thr_acc->locksetA ); /* read ==> use all locks */
wnew = mk_SHVAL_ShR( tset, lset );
- stats__msm_r32_Excl_to_ShR++;
- return wnew;
+ stats__msm_read_Excl_to_ShR++;
+ goto changed;
}
/*NOTREACHED*/
}
@@ -2892,11 +3013,11 @@
lset_old,
add_BHL(thr_acc->locksetA)
/* read ==> use all locks */ );
- UInt wnew = mk_SHVAL_ShR( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShR( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
- stats__msm_r32_ShR_to_ShR++;
- return wnew;
+ stats__msm_read_ShR_to_ShR++;
+ goto changed;
}
/* Shared-Modified */
@@ -2913,7 +3034,7 @@
lset_old,
add_BHL(thr_acc->locksetA)
/* read ==> use all locks */ );
- UInt wnew = mk_SHVAL_ShM( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShM( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
if (TC_(isEmptyWS)(univ_lsets, lset_new)
@@ -2922,16 +3043,16 @@
False/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_r32_ShM_to_ShM++;
- return wnew;
+ stats__msm_read_ShM_to_ShM++;
+ goto changed;
}
/* New */
if (is_SHVAL_New(wold)) {
/* read New -> Excl(segid) */
- UInt wnew = mk_SHVAL_Excl( thr_acc->csegid );
- stats__msm_r32_New_to_Excl++;
- return wnew;
+ wnew = mk_SHVAL_Excl( thr_acc->csegid );
+ stats__msm_read_New_to_Excl++;
+ goto changed;
}
/* NoAccess */
@@ -2942,12 +3063,21 @@
VG_(printf)(
"msm__handle_read_aligned_32(thr=%p, addr=%p): NoAccess\n",
thr_acc, (void*)a );
- stats__msm_r32_NoAccess++;
- return wold; /* no change */
+ stats__msm_read_NoAccess++;
+ /*NOCHANGE*/return wold; /* no change */
}
/* hmm, bogus state */
tl_assert(0);
+
+ changed:
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (a <= clo_trace_addr && clo_trace_addr < a+szB
+ && wold != wnew) {
+ msm__show_state_change( thr_acc, a, szB, 'r', wold, wnew );
+ }
+ }
+ return wnew;
}
/* Similar to msm__handle_read, compute a new 32-bit shadow word
@@ -2956,17 +3086,21 @@
static
UInt msm__handle_write ( Thread* thr_acc, Addr a, UInt wold, Int szB )
{
+ UInt wnew = SHVAL_Invalid;
+
tl_assert(is_sane_Thread(thr_acc));
if (0) VG_(printf)("write32 thr=%p %p\n", thr_acc, a);
/* New */
- if (is_SHVAL_New(wold)) {
+ if (LIKELY(is_SHVAL_New(wold))) {
/* write New -> Excl(segid) */
- UInt wnew = mk_SHVAL_Excl( thr_acc->csegid );
- stats__msm_w32_New_to_Excl++;
- return wnew;
+ wnew = mk_SHVAL_Excl( thr_acc->csegid );
+ stats__msm_write_New_to_Excl++;
+ goto changed;
}
+
+ /* Exclusive */
if (is_SHVAL_Excl(wold)) {
// I believe is identical to case for read Excl
// apart from enters ShM rather than ShR
@@ -2982,18 +3116,17 @@
tl_assert(is_sane_SegmentID(segid_old));
if (segid_old == thr_acc->csegid) {
/* no change */
- stats__msm_w32_Excl_nochange++;
- return wold;
+ stats__msm_write_Excl_nochange++;
+ /*NOCHANGE*/return wold;
}
if (happens_before(segid_old, thr_acc->csegid)) {
/* -> Excl(segid-of-this-thread) */
- UInt wnew = mk_SHVAL_Excl(thr_acc->csegid);
- stats__msm_w32_Excl_transfer++;
- return wnew;
+ wnew = mk_SHVAL_Excl(thr_acc->csegid);
+ stats__msm_write_Excl_transfer++;
+ goto changed;
}
/* else */ {
/* Enter the shared-modified (ShM) state. */
- UInt wnew;
WordSetID tset, lset;
/* This location has been accessed by precisely two threads.
Make an appropriate tset. */
@@ -3009,8 +3142,8 @@
a, True/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_w32_Excl_to_ShM++;
- return wnew;
+ stats__msm_write_Excl_to_ShM++;
+ goto changed;
}
/*NOTREACHED*/
}
@@ -3031,7 +3164,7 @@
thr_acc->locksetW
/* write ==> use only w-held locks */
);
- UInt wnew = mk_SHVAL_ShM( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShM( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
if (TC_(isEmptyWS)(univ_lsets, lset_new)) {
@@ -3039,8 +3172,8 @@
True/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_w32_ShR_to_ShM++;
- return wnew;
+ stats__msm_write_ShR_to_ShM++;
+ goto changed;
}
/* Shared-Modified */
@@ -3059,7 +3192,7 @@
thr_acc->locksetW
/* write ==> use only w-held locks */
);
- UInt wnew = mk_SHVAL_ShM( tset_new, lset_new );
+ /*UInt*/ wnew = mk_SHVAL_ShM( tset_new, lset_new );
if (lset_old != lset_new)
record_last_lock_lossage(a,lset_old,lset_new);
if (TC_(isEmptyWS)(univ_lsets, lset_new)
@@ -3068,8 +3201,8 @@
True/*isWrite*/, szB, wold, wnew,
maybe_get_lastlock_initpoint(a) );
}
- stats__msm_w32_ShM_to_ShM++;
- return wnew;
+ stats__msm_write_ShM_to_ShM++;
+ goto changed;
}
/* NoAccess */
@@ -3080,14 +3213,23 @@
VG_(printf)(
"msm__handle_write_aligned_32(thr=%p, addr=%p): NoAccess\n",
thr_acc, (void*)a );
- stats__msm_w32_NoAccess++;
- return wold;
+ stats__msm_write_NoAccess++;
+ /*NOCHANGE*/return wold;
}
/* hmm, bogus state */
VG_(printf)("msm__handle_write_aligned_32: bogus old state 0x%x\n",
wold);
tl_assert(0);
+
+ changed:
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (a <= clo_trace_addr && clo_trace_addr < a+szB
+ && wold != wnew) {
+ msm__show_state_change( thr_acc, a, szB, 'w', wold, wnew );
+ }
+ }
+ return wnew;
}
@@ -3097,8 +3239,8 @@
static void laog__pre_thread_acquires_lock ( Thread*, Lock* ); /* fwds */
static void laog__handle_lock_deletions ( WordSetID ); /* fwds */
+static inline Thread* get_current_Thread ( void ); /* fwds */
-
/* ------------ CacheLineF and CacheLineZ related ------------ */
static void write_twobit_array ( UChar* arr, UWord ix, UWord b2 ) {
@@ -4435,6 +4577,15 @@
UInt sv;
stats__cline_copy8s++;
sv = shadow_mem_get8( src );
+
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (dst == clo_trace_addr) {
+ Thread* thr = get_current_Thread();
+ UInt sv_old = shadow_mem_get8( dst );
+ msm__show_state_change( thr, dst, 1, 'w', sv_old, sv );
+ }
+ }
+
shadow_mem_set8( NULL/*unused*/, dst, sv );
}
@@ -4565,6 +4716,12 @@
static void shadow_mem_make_New ( Thread* thr, Addr a, SizeT len )
{
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (len > 0 && a <= clo_trace_addr && clo_trace_addr < a+len) {
+ UInt sv_old = shadow_mem_get8( clo_trace_addr );
+ msm__show_state_change( thr, a, (Int)len, 'p', sv_old, SHVAL_New );
+ }
+ }
shadow_mem_modify_range( thr, a, len,
shadow_mem_set8,
shadow_mem_set16,
@@ -4675,6 +4832,13 @@
/* --- Step 2 --- */
+ if (UNLIKELY(clo_trace_level > 0)) {
+ if (len > 0 && firstA <= clo_trace_addr && clo_trace_addr <= lastA) {
+ UInt sv_old = shadow_mem_get8( clo_trace_addr );
+ msm__show_state_change( thr, firstA, (Int)len, 'p',
+ sv_old, SHVAL_NoAccess );
+ }
+ }
shadow_mem_modify_range( thr, firstA, len,
shadow_mem_set8,
shadow_mem_set16,
@@ -5135,7 +5299,7 @@
- for uses definitely within client code, use
get_current_Thread_in_C_C.
- - for all other uses, use get_current_Thread_general.
+ - for all other uses, use get_current_Thread.
*/
static Thread* current_Thread = NULL;
@@ -7387,7 +7551,7 @@
static void record_error_Race ( Thread* thr,
Addr data_addr, Bool isWrite, Int szB,
- UInt old_w32, UInt new_w32,
+ UInt old_sv, UInt new_sv,
ExeContext* mb_lastlock ) {
XError xe;
tl_assert( is_sane_Thread(thr) );
@@ -7396,8 +7560,8 @@
xe.XE.Race.data_addr = data_addr;
xe.XE.Race.szB = szB;
xe.XE.Race.isWrite = isWrite;
- xe.XE.Race.new_state = new_w32;
- xe.XE.Race.old_state = old_w32;
+ xe.XE.Race.new_state = new_sv;
+ xe.XE.Race.old_state = old_sv;
xe.XE.Race.mb_lastlock = mb_lastlock;
xe.XE.Race.thr = thr;
// FIXME: tid vs thr
@@ -7990,6 +8154,13 @@
else if (VG_CLO_STREQ(arg, "--cmp-race-err-addrs=yes"))
clo_cmp_race_err_addrs = True;
+ else if (VG_CLO_STREQN(13, arg, "--trace-addr=")) {
+ clo_trace_addr = VG_(atoll16)(&arg[13]);
+ if (clo_trace_level == 0)
+ clo_trace_level = 1;
+ }
+ else VG_BNUM_CLO(arg, "--trace-level", clo_trace_level, 0, 2)
+
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
@@ -8001,6 +8172,8 @@
VG_(printf)(
" --happens-before=none|threads|condvars [condvars] consider no events,\n"
" thread create/join, thread create/join/cvsignal/cvwait as sync points\n"
+" --trace-addr=0xXXYYZZ show all state changes for address 0xXXYYZZ\n"
+" --trace-level=0|1|2 verbosity level of --trace-addr [1]\n"
);
VG_(replacement_malloc_print_usage)();
}
@@ -8082,19 +8255,19 @@
VG_(printf)("\n");
VG_(printf)(" msm: %,12lu %,12lu rd/wr_Excl_nochange\n",
- stats__msm_r32_Excl_nochange, stats__msm_w32_Excl_nochange);
+ stats__msm_read_Excl_nochange, stats__msm_write_Excl_nochange);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_Excl_transfer\n",
- stats__msm_r32_Excl_transfer, stats__msm_w32_Excl_transfer);
+ stats__msm_read_Excl_transfer, stats__msm_write_Excl_transfer);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_Excl_to_ShR/ShM\n",
- stats__msm_r32_Excl_to_ShR, stats__msm_w32_Excl_to_ShM);
+ stats__msm_read_Excl_to_ShR, stats__msm_write_Excl_to_ShM);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_ShR_to_ShR/ShM\n",
- stats__msm_r32_ShR_to_ShR, stats__msm_w32_ShR_to_ShM);
+ stats__msm_read_ShR_to_ShR, stats__msm_write_ShR_to_ShM);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_ShM_to_ShM\n",
- stats__msm_r32_ShM_to_ShM, stats__msm_w32_ShM_to_ShM);
+ stats__msm_read_ShM_to_ShM, stats__msm_write_ShM_to_ShM);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_New_to_Excl\n",
- stats__msm_r32_New_to_Excl, stats__msm_w32_New_to_Excl);
+ stats__msm_read_New_to_Excl, stats__msm_write_New_to_Excl);
VG_(printf)(" msm: %,12lu %,12lu rd/wr_NoAccess\n",
- stats__msm_r32_NoAccess, stats__msm_w32_NoAccess);
+ stats__msm_read_NoAccess, stats__msm_write_NoAccess);
VG_(printf)("\n");
VG_(printf)(" secmaps: %,10lu allocd (%,12lu g-a-range)\n",
|