文档目录

一、Valgrind 的 TSan 替代方案

之前讲过 ThreadSanitizer 能检测数据竞争,但需要重编译。如果你有一个已经编译好的二进制(或者第三方库没源码),可以用 Helgrind 或 DRD 做运行时数据竞争检测。

# Helgrind(更详细,但更慢)
valgrind --tool=helgrind ./my_multithread_program

# DRD(更快一点,但可能漏报)
valgrind --tool=drd ./my_multithread_program

二、输出示例

#include <thread>
#include <iostream>

int counter = 0;  // 没有锁保护

void worker() {
    for (int i = 0; i < 100000; i++) {
        counter++;  // 数据竞争!
    }
}

int main() {
    std::thread t1(worker);
    std::thread t2(worker);
    t1.join();
    t2.join();
    std::cout << counter << std::endl;
    return 0;
}
valgrind --tool=drd ./race

# 输出:
# DRD: data race on address 0x601050 in object 'counter'
#   Conflicting store by thread 1 at 0x400B34: worker() race.cpp:6
#   Conflicting load by thread 2 at 0x400B38: worker() race.cpp:6
#   Allocation context: BSS section of /tmp/race

三、Helgrind vs DRD vs TSan

工具 是否需要重编译 运行速度 精确度
TSan(-fsanitize=thread) 需要 慢 5-10x 高
DRD(valgrind) 不需要 慢 20-30x 中
Helgrind(valgrind) 不需要 慢 20-30x 高
实际选择:
  如果你有源码:用 -fsanitize=thread(最快最准)
  如果你只有二进制:用 DRD 或 Helgrind
  Helgrind 的报错比 DRD 详细,但慢一点