VG_(message)(Vg_UserMsg, "Possible data race %s variable at %p %(y",
err->string, err->addr, err->addr );
pp_ExeContext();
+ pp_AddrInfo(err->addr, &extra->addrinfo);
switch(extra->prevstate.state) {
case Vge_Virgin:
if (*msg)
VG_(message)(Vg_UserMsg, " Previous state: %s", msg);
- pp_AddrInfo(err->addr, &extra->addrinfo);
-
if (clo_execontext == EC_Some && extra->lasttouched.eip != 0) {
Char file[100];
UInt line;
Addr eip = extra->lasttouched.eip;
- VG_(message)(Vg_UserMsg, " Word at %p last accessed", err->addr);
+ VG_(message)(Vg_UserMsg, " Word at %p last changed state", err->addr);
if (VG_(get_filename_linenum)(eip, file, sizeof(file), &line)) {
VG_(message)(Vg_UserMsg, " at %p: %y (%s:%u)",
VG_(message)(Vg_UserMsg, " at %p: %y", eip, eip);
}
} else if (clo_execontext == EC_All && extra->lasttouched.ec != NULL) {
- VG_(message)(Vg_UserMsg, " Word at %p last accessed", err->addr);
+ VG_(message)(Vg_UserMsg, " Word at %p last changed state", err->addr);
VG_(pp_ExeContext)(extra->lasttouched.ec);
}
#define DEBUG_STATE(args...)
#endif
-
-static void eraser_mem_read(Addr a, UInt size, ThreadState *tst)
+static void eraser_mem_read_word(Addr a, ThreadId tid, ThreadState *tst)
{
- ThreadId tid;
- ThreadLifeSeg *tls;
shadow_word* sword;
- Addr end;
shadow_word prevstate;
+ ThreadLifeSeg *tls;
const LockSet *ls;
+ Bool statechange = False;
- end = ROUNDUP(a+size, 4);
- a = ROUNDDN(a, 4);
-
- if (tst == NULL)
- tid = VG_(get_current_tid)();
- else
- tid = VG_(get_tid_from_ThreadState)(tst);
+ static const void *const states[4] = {
+ [Vge_Virgin] &&st_virgin,
+ [Vge_Excl] &&st_excl,
+ [Vge_Shar] &&st_shar,
+ [Vge_SharMod] &&st_sharmod,
+ };
tls = thread_seg[tid];
sk_assert(tls != NULL && tls->tid == tid);
- for ( ; a < end; a += 4) {
- static const void *const states[4] = {
- [Vge_Virgin] &&st_virgin,
- [Vge_Excl] &&st_excl,
- [Vge_Shar] &&st_shar,
- [Vge_SharMod] &&st_sharmod,
- };
-
- sword = get_sword_addr(a);
- if (sword == SEC_MAP_ACCESS) {
- VG_(printf)("read distinguished 2ndary map! 0x%x\n", a);
- continue;
- }
+ sword = get_sword_addr(a);
+ if (sword == SEC_MAP_ACCESS) {
+ VG_(printf)("read distinguished 2ndary map! 0x%x\n", a);
+ return;
+ }
- prevstate = *sword;
+ prevstate = *sword;
- goto *states[sword->state];
+ goto *states[sword->state];
- /* This looks like reading of unitialised memory, may be legit. Eg.
- * calloc() zeroes its values, so untouched memory may actually be
- * initialised. Leave that stuff to Valgrind. */
- st_virgin:
- if (TID_INDICATING_NONVIRGIN == sword->other) {
- DEBUG_STATE("Read VIRGIN --> EXCL: %8x, %u\n", a, tid);
- if (DEBUG_VIRGIN_READS)
- dump_around_a(a);
- } else {
- DEBUG_STATE("Read SPECIAL --> EXCL: %8x, %u\n", a, tid);
- }
- *sword = SW(Vge_Excl, packTLS(tls)); /* remember exclusive owner */
+ /* This looks like reading of unitialised memory, may be legit. Eg.
+ * calloc() zeroes its values, so untouched memory may actually be
+ * initialised. Leave that stuff to Valgrind. */
+ st_virgin:
+ if (TID_INDICATING_NONVIRGIN == sword->other) {
+ DEBUG_STATE("Read VIRGIN --> EXCL: %8x, %u\n", a, tid);
+ if (DEBUG_VIRGIN_READS)
+ dump_around_a(a);
+ } else {
+ DEBUG_STATE("Read SPECIAL --> EXCL: %8x, %u\n", a, tid);
+ }
+ statechange = True;
+ *sword = SW(Vge_Excl, packTLS(tls)); /* remember exclusive owner */
+ tls->refcount++;
+ goto done;
+
+ st_excl: {
+ ThreadLifeSeg *sw_tls = unpackTLS(sword->other);
+
+ if (tls == sw_tls) {
+ DEBUG_STATE("Read EXCL: %8x, %u\n", a, tid);
+ } else if (unpackTLS(TLSP_INDICATING_ALL) == sw_tls) {
+ DEBUG_STATE("Read EXCL/ERR: %8x, %u\n", a, tid);
+ } else if (tlsIsDisjoint(tls, sw_tls)) {
+ DEBUG_STATE("Read EXCL(%u) --> EXCL: %8x, %u\n", sw_tls->tid, a, tid);
+ statechange = True;
+ sword->other = packTLS(tls);
+ sw_tls->refcount--;
tls->refcount++;
- goto done;
-
- st_excl: {
- ThreadLifeSeg *sw_tls = unpackTLS(sword->other);
-
- if (tls == sw_tls) {
- DEBUG_STATE("Read EXCL: %8x, %u\n", a, tid);
- } else if (unpackTLS(TLSP_INDICATING_ALL) == sw_tls) {
- DEBUG_STATE("Read EXCL/ERR: %8x, %u\n", a, tid);
- } else if (tlsIsDisjoint(tls, sw_tls)) {
- DEBUG_STATE("Read EXCL(%u) --> EXCL: %8x, %u\n", sw_tls->tid, a, tid);
- sword->other = packTLS(tls);
- sw_tls->refcount--;
- tls->refcount++;
- } else {
- DEBUG_STATE("Read EXCL(%u) --> SHAR: %8x, %u\n", sw_tls->tid, a, tid);
- sw_tls->refcount--;
- *sword = SW(Vge_Shar, packLockSet(thread_locks[tid]));
+ } else {
+ DEBUG_STATE("Read EXCL(%u) --> SHAR: %8x, %u\n", sw_tls->tid, a, tid);
+ sw_tls->refcount--;
+ statechange = True;
+ *sword = SW(Vge_Shar, packLockSet(thread_locks[tid]));
- if (DEBUG_MEM_LOCKSET_CHANGES)
- print_LockSet("excl read locks", unpackLockSet(sword->other));
- }
- goto done;
+ if (DEBUG_MEM_LOCKSET_CHANGES)
+ print_LockSet("excl read locks", unpackLockSet(sword->other));
}
+ goto done;
+ }
- st_shar:
- DEBUG_STATE("Read SHAR: %8x, %u\n", a, tid);
- sword->other = packLockSet(intersect(unpackLockSet(sword->other),
- thread_locks[tid]));
- goto done;
+ st_shar:
+ DEBUG_STATE("Read SHAR: %8x, %u\n", a, tid);
+ sword->other = packLockSet(intersect(unpackLockSet(sword->other),
+ thread_locks[tid]));
+ statechange = sword->other != prevstate.other;
+ goto done;
- st_sharmod:
- DEBUG_STATE("Read SHAR_MOD: %8x, %u\n", a, tid);
- ls = intersect(unpackLockSet(sword->other),
- thread_locks[tid]);
- sword->other = packLockSet(ls);
+ st_sharmod:
+ DEBUG_STATE("Read SHAR_MOD: %8x, %u\n", a, tid);
+ ls = intersect(unpackLockSet(sword->other),
+ thread_locks[tid]);
+ sword->other = packLockSet(ls);
- if (isempty(ls)) {
- record_eraser_error(tst, a, False /* !is_write */, prevstate);
- }
- goto done;
+ statechange = sword->other != prevstate.other;
- done:
- if (clo_execontext != EC_None) {
- EC_EIP eceip;
+ if (isempty(ls)) {
+ record_eraser_error(tst, a, False /* !is_write */, prevstate);
+ }
+ goto done;
- if (clo_execontext == EC_Some)
- eceip.eip = VG_(get_EIP)(tst);
- else
- eceip.ec = VG_(get_ExeContext)(tst);
- setExeContext(a, eceip);
- }
+ done:
+ if (clo_execontext != EC_None && statechange) {
+ EC_EIP eceip;
+
+ if (clo_execontext == EC_Some)
+ eceip.eip = VG_(get_EIP)(tst);
+ else
+ eceip.ec = VG_(get_ExeContext)(tst);
+ setExeContext(a, eceip);
}
}
-static void eraser_mem_write(Addr a, UInt size, ThreadState *tst)
+static void eraser_mem_read(Addr a, UInt size, ThreadState *tst)
{
ThreadId tid;
- ThreadLifeSeg *tls;
- shadow_word* sword;
Addr end;
- shadow_word prevstate;
end = ROUNDUP(a+size, 4);
a = ROUNDDN(a, 4);
tid = VG_(get_current_tid)();
else
tid = VG_(get_tid_from_ThreadState)(tst);
-
+
+
+ for ( ; a < end; a += 4)
+ eraser_mem_read_word(a, tid, tst);
+}
+
+static void eraser_mem_write_word(Addr a, ThreadId tid, ThreadState *tst)
+{
+ ThreadLifeSeg *tls;
+ shadow_word* sword;
+ shadow_word prevstate;
+ Bool statechange = False;
+ static const void *const states[4] = {
+ [Vge_Virgin] &&st_virgin,
+ [Vge_Excl] &&st_excl,
+ [Vge_Shar] &&st_shar,
+ [Vge_SharMod] &&st_sharmod,
+ };
+
tls = thread_seg[tid];
sk_assert(tls != NULL && tls->tid == tid);
- for ( ; a < end; a += 4) {
- static const void *const states[4] = {
- [Vge_Virgin] &&st_virgin,
- [Vge_Excl] &&st_excl,
- [Vge_Shar] &&st_shar,
- [Vge_SharMod] &&st_sharmod,
- };
-
- sword = get_sword_addr(a);
- if (sword == SEC_MAP_ACCESS) {
- VG_(printf)("read distinguished 2ndary map! 0x%x\n", a);
- continue;
- }
+ sword = get_sword_addr(a);
+ if (sword == SEC_MAP_ACCESS) {
+ VG_(printf)("read distinguished 2ndary map! 0x%x\n", a);
+ return;
+ }
- prevstate = *sword;
+ prevstate = *sword;
- goto *states[sword->state];
+ goto *states[sword->state];
- st_virgin:
- if (TID_INDICATING_NONVIRGIN == sword->other)
- DEBUG_STATE("Write VIRGIN --> EXCL: %8x, %u\n", a, tid);
- else
- DEBUG_STATE("Write SPECIAL --> EXCL: %8x, %u\n", a, tid);
- *sword = SW(Vge_Excl, packTLS(tls));/* remember exclusive owner */
+ st_virgin:
+ if (TID_INDICATING_NONVIRGIN == sword->other)
+ DEBUG_STATE("Write VIRGIN --> EXCL: %8x, %u\n", a, tid);
+ else
+ DEBUG_STATE("Write SPECIAL --> EXCL: %8x, %u\n", a, tid);
+ statechange = True;
+ *sword = SW(Vge_Excl, packTLS(tls));/* remember exclusive owner */
+ tls->refcount++;
+ goto done;
+
+ st_excl: {
+ ThreadLifeSeg *sw_tls = unpackTLS(sword->other);
+
+ if (tls == sw_tls) {
+ DEBUG_STATE("Write EXCL: %8x, %u\n", a, tid);
+ goto done;
+ } else if (unpackTLS(TLSP_INDICATING_ALL) == sw_tls) {
+ DEBUG_STATE("Write EXCL/ERR: %8x, %u\n", a, tid);
+ goto done;
+ } else if (tlsIsDisjoint(tls, sw_tls)) {
+ DEBUG_STATE("Write EXCL(%u) --> EXCL: %8x, %u\n", sw_tls->tid, a, tid);
+ sword->other = packTLS(tls);
+ sw_tls->refcount--;
tls->refcount++;
- goto done;
-
- st_excl: {
- ThreadLifeSeg *sw_tls = unpackTLS(sword->other);
-
- if (tls == sw_tls) {
- DEBUG_STATE("Write EXCL: %8x, %u\n", a, tid);
- goto done;
- } else if (unpackTLS(TLSP_INDICATING_ALL) == sw_tls) {
- DEBUG_STATE("Write EXCL/ERR: %8x, %u\n", a, tid);
- goto done;
- } else if (tlsIsDisjoint(tls, sw_tls)) {
- DEBUG_STATE("Write EXCL(%u) --> EXCL: %8x, %u\n", sw_tls->tid, a, tid);
- sword->other = packTLS(tls);
- sw_tls->refcount--;
- tls->refcount++;
- goto done;
- } else {
- DEBUG_STATE("Write EXCL(%u) --> SHAR_MOD: %8x, %u\n", sw_tls->tid, a, tid);
- sw_tls->refcount--;
- *sword = SW(Vge_SharMod, packLockSet(thread_locks[tid]));
- if(DEBUG_MEM_LOCKSET_CHANGES)
- print_LockSet("excl write locks", unpackLockSet(sword->other));
- goto SHARED_MODIFIED;
- }
+ goto done;
+ } else {
+ DEBUG_STATE("Write EXCL(%u) --> SHAR_MOD: %8x, %u\n", sw_tls->tid, a, tid);
+ statechange = True;
+ sw_tls->refcount--;
+ *sword = SW(Vge_SharMod, packLockSet(thread_locks[tid]));
+ if(DEBUG_MEM_LOCKSET_CHANGES)
+ print_LockSet("excl write locks", unpackLockSet(sword->other));
+ goto SHARED_MODIFIED;
}
+ }
- st_shar:
- DEBUG_STATE("Write SHAR --> SHAR_MOD: %8x, %u\n", a, tid);
- sword->state = Vge_SharMod;
- sword->other = packLockSet(intersect(unpackLockSet(sword->other),
- thread_locks[tid]));
- goto SHARED_MODIFIED;
-
- st_sharmod:
- DEBUG_STATE("Write SHAR_MOD: %8x, %u\n", a, tid);
- sword->other = packLockSet(intersect(unpackLockSet(sword->other),
- thread_locks[tid]));
- SHARED_MODIFIED:
- if (isempty(unpackLockSet(sword->other))) {
- record_eraser_error(tst, a, True /* is_write */, prevstate);
- }
- goto done;
+ st_shar:
+ DEBUG_STATE("Write SHAR --> SHAR_MOD: %8x, %u\n", a, tid);
+ sword->state = Vge_SharMod;
+ sword->other = packLockSet(intersect(unpackLockSet(sword->other),
+ thread_locks[tid]));
+ statechange = True;
+ goto SHARED_MODIFIED;
- done:
- if (clo_execontext != EC_None) {
- EC_EIP eceip;
+ st_sharmod:
+ DEBUG_STATE("Write SHAR_MOD: %8x, %u\n", a, tid);
+ sword->other = packLockSet(intersect(unpackLockSet(sword->other),
+ thread_locks[tid]));
+ statechange = sword->other != prevstate.other;
- if (clo_execontext == EC_Some)
- eceip.eip = VG_(get_EIP)(tst);
- else
- eceip.ec = VG_(get_ExeContext)(tst);
- setExeContext(a, eceip);
- }
+ SHARED_MODIFIED:
+ if (isempty(unpackLockSet(sword->other))) {
+ record_eraser_error(tst, a, True /* is_write */, prevstate);
+ }
+ goto done;
+
+ done:
+ if (clo_execontext != EC_None && statechange) {
+ EC_EIP eceip;
+
+ if (clo_execontext == EC_Some)
+ eceip.eip = VG_(get_EIP)(tst);
+ else
+ eceip.ec = VG_(get_ExeContext)(tst);
+ setExeContext(a, eceip);
}
}
+static void eraser_mem_write(Addr a, UInt size, ThreadState *tst)
+{
+ ThreadId tid;
+ Addr end;
+
+ end = ROUNDUP(a+size, 4);
+ a = ROUNDDN(a, 4);
+
+ if (tst == NULL)
+ tid = VG_(get_current_tid)();
+ else
+ tid = VG_(get_tid_from_ThreadState)(tst);
+
+ for ( ; a < end; a += 4)
+ eraser_mem_write_word(a, tid, tst);
+}
+
#undef DEBUG_STATE
static void eraser_mem_help_read_1(Addr a)