ThreadSanitizer(TSan)是Clang/GCC提供的高精度动态数据竞争检测工具,需用支持版本编译全部代码、加-pthread和-O1,运行时报详细竞态信息,适用于调试而非生产环境。
ThreadSanitizer(TSan)是 Clang 和 GCC 提供的动态数据竞争检测工具,专为 C/C++ 多线程程序设计。它通过插桩内存访问指令、记录线程与锁状态,在运行时实时识别未同步的并发读写(data race),准确率高、误报少,是调试多线程 bug 的首选工具之一。
必须用支持 TSan 的编译器(Clang ≥ 3.2 或 GCC ≥ 4.8),且需同时编译所有源文件(包括第三方静态库,否则可能漏检):
clang++ -fsanitize=thread -g -O1 -pthread main.cpp -o main
g++ -fsanitize=thread -g -O1 -pthread main.cpp -o main
-fPIE -pie 编译可执行文件以支持插桩程序运行中一旦发现数据竞争,TSan 会立即打印带堆栈的详细报告到 stderr,包含:
例如报告中出现 WARNING: ThreadSanitizer: data race,紧接着两段 “Read of size X at …” 和 “Previous write of size X at …”,即表示一个典型竞态。
TSan 基于 happens-before 模型,对某些模式需手动标注:
std::atomic 或 __atomic_* 系列函数访问的变量默认不报竞态;但若混用原子与非原子访问同一地址,仍会报警——这是正确行为,应统一为原子访问__tsan_acquire/__tsan_release 或 __attribute__((no_sanitize("thread"
))) 局部禁用(慎用)TSan 不适合生产环境(性能下降 5–15×,内存开销 +2–3×),但非常适合 CI 和本地调试:
-fsanitize=thread 编译,配合 --gtest_filter=MyThreadTest.* 快速定位问题Tsan_OPTIONS="halt_on_error=1 abort_on_error=1 second_deadlock_timeout=5"
-fsanitize=thread,address 在 Clang 中合法,在 GCC 中不支持,应分开运行