Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,8 @@ int Finalize(ThreadState *thr) {

failed = OnFinalize(failed);

LogFlushData();

return failed ? common_flags()->exitcode : 0;
}

Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/tsan/rtl/tsan_rtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@

namespace __tsan {

void LogFlushData();

#if !SANITIZER_GO
struct MapUnmapCallback;
# if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \
Expand Down
42 changes: 42 additions & 0 deletions compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,45 @@

namespace __tsan {

// How many log accesses to flush at one time
#define STATS_BUFFER_COUNT 10000000

struct AccessData {
uptr Address;
uptr Size;
Tid ThreadId;
u8 Type;
};

static Mutex LogMutex;
static u32 LogDataOffset = 0;
static AccessData LogData[STATS_BUFFER_COUNT];
static char LogString[STATS_BUFFER_COUNT * 64];

void LogFlushData() {
u32 Offset = 0;
for (u32 I = 0; I < LogDataOffset; ++I)
Offset += internal_snprintf(LogString + Offset,
sizeof(LogString) - Offset,
" > 0x%8lx %lu 0x%02x %u\n",
LogData[I].Address,
LogData[I].Size,
LogData[I].Type,
LogData[I].ThreadId);
Printf("%s", LogString);
}

void LogMemoryAccess(uptr Address, uptr Size,
AccessType Type, Tid ThreadId) {
LogMutex.Lock();
LogData[LogDataOffset++] = {Address, Size, ThreadId, static_cast<u8>(Type)};
if (LogDataOffset == STATS_BUFFER_COUNT) {
LogFlushData();
LogDataOffset = 0;
}
LogMutex.Unlock();
}

ALWAYS_INLINE USED bool TryTraceMemoryAccess(ThreadState* thr, uptr pc,
uptr addr, uptr size,
AccessType typ) {
Expand Down Expand Up @@ -419,6 +458,7 @@ NOINLINE void TraceRestartMemoryAccess(ThreadState* thr, uptr pc, uptr addr,

ALWAYS_INLINE USED void MemoryAccess(ThreadState* thr, uptr pc, uptr addr,
uptr size, AccessType typ) {
LogMemoryAccess(addr, size, typ, thr->tid);
RawShadow* shadow_mem = MemToShadow(addr);
UNUSED char memBuf[4][64];
DPrintf2("#%d: Access: %d@%d %p/%zd typ=0x%x {%s, %s, %s, %s}\n", thr->tid,
Expand Down Expand Up @@ -454,6 +494,7 @@ void RestartMemoryAccess16(ThreadState* thr, uptr pc, uptr addr,
ALWAYS_INLINE USED void MemoryAccess16(ThreadState* thr, uptr pc, uptr addr,
AccessType typ) {
const uptr size = 16;
LogMemoryAccess(addr, size, typ, thr->tid);
FastState fast_state = thr->fast_state;
if (UNLIKELY(fast_state.GetIgnoreBit()))
return;
Expand Down Expand Up @@ -666,6 +707,7 @@ template <bool is_read>
void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
const AccessType typ =
(is_read ? kAccessRead : kAccessWrite) | kAccessNoRodata;
LogMemoryAccess(addr, size, typ, thr->tid);
RawShadow* shadow_mem = MemToShadow(addr);
DPrintf2("#%d: MemoryAccessRange: @%p %p size=%d is_read=%d\n", thr->tid,
(void*)pc, (void*)addr, (int)size, is_read);
Expand Down