The test contains a race in memset. The size of reported race depends on how the accessed memory range split into granules inside of tsan runtime. The test used to report access of size 8, because presumably the buffer ended up being aligned to 8 bytes. But after some unrelated changes this test started to report accesses of size 1 (presumably .data layout changed), which makes the test fail. Guarantee alignment of the buf object explicitly. Reviewed By: melver Differential Revision: https://reviews.llvm.org/D107149
53 lines
1.4 KiB
C++
53 lines
1.4 KiB
C++
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
|
|
#include "../test.h"
|
|
#include <memory.h>
|
|
|
|
// A reproducer for a known issue.
|
|
// See reference to double_race.cpp in tsan_rtl_report.cpp for an explanation.
|
|
|
|
long long buf[2];
|
|
volatile int nreport;
|
|
|
|
void __sanitizer_report_error_summary(const char *summary) {
|
|
nreport++;
|
|
}
|
|
|
|
const int kEventPCBits = 61;
|
|
|
|
extern "C" bool __tsan_symbolize_external(unsigned long pc, char *func_buf,
|
|
unsigned long func_siz,
|
|
char *file_buf,
|
|
unsigned long file_siz, int *line,
|
|
int *col) {
|
|
if (pc >> kEventPCBits) {
|
|
printf("bad PC passed to __tsan_symbolize_external: %lx\n", pc);
|
|
_exit(1);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void *Thread(void *arg) {
|
|
barrier_wait(&barrier);
|
|
memset(buf, 2, sizeof(buf));
|
|
return 0;
|
|
}
|
|
|
|
int main() {
|
|
barrier_init(&barrier, 2);
|
|
pthread_t t;
|
|
pthread_create(&t, 0, Thread, 0);
|
|
memset(buf, 1, sizeof(buf));
|
|
barrier_wait(&barrier);
|
|
pthread_join(t, 0);
|
|
return 0;
|
|
}
|
|
|
|
// CHECK: WARNING: ThreadSanitizer: data race
|
|
// CHECK: Write of size 8 at {{.*}} by thread T1:
|
|
// CHECK: #0 memset
|
|
// CHECK: #{{[12]}} Thread
|
|
// CHECK-NOT: bad PC passed to __tsan_symbolize_external
|
|
// CHECK: WARNING: ThreadSanitizer: data race
|
|
// CHECK: Write of size 8 at {{.*}} by thread T1:
|
|
// CHECK: #0 Thread
|