【发布时间】:2016-01-05 10:15:34
【问题描述】:
考虑以下示例:
#include <iostream>
int main () {
int i = 0;
#pragma omp parallel
{
#pragma omp critical
{
++i;
}
}
std::cout << i;
}
用g++ -fopenmp -fsanitize=thread编译并运行yield
警告:ThreadSanitizer:数据竞争 (pid=9576)
线程 T1 在 0x7ffdc170f600 读取大小 4:
#0 main._omp_fn.0 (a.out+0x000000400d20)
#1 gomp_thread_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:118 (libgomp.so.1+0x00000000f42d)线程 T2 先前在 0x7ffdc170f600 写入大小 4:
#0 main._omp_fn.0 (a.out+0x000000400d35)
#1 gomp_thread_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:118 (libgomp.so.1+0x00000000f42d)位置是主线程的堆栈。
主线程在以下位置创建的线程 T1 (tid=9578, running):
#0 pthread_create /build/gcc/src/gcc-5.2.0/libsanitizer/tsan/tsan_interceptors.cc:895 (libtsan.so.0+0x000000027a37)
#1 gomp_team_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:796 (libgomp.so.1+0x00000000f98f)
#2 __libc_start_main (libc.so.6+0x00000002060f)主线程在以下位置创建的线程 T2 (tid=9579, running):
#0 pthread_create /build/gcc/src/gcc-5.2.0/libsanitizer/tsan/tsan_interceptors.cc:895 (libtsan.so.0+0x000000027a37)
#1 gomp_team_start /build/gcc/src/gcc-5.2.0/libgomp/team.c:796 (libgomp.so.1+0x00000000f98f)
#2 __libc_start_main (libc.so.6+0x00000002060f)摘要:ThreadSanitizer:数据竞争 ??:0 main._omp_fn.0
据我所知,这是误报。有没有办法避免这种情况?
(使用 clang 和 libomp 也可以。)
【问题讨论】:
-
如果要分析代码,还需要使用 TSAN 构建 OpenMP 运行时库;否则添加抑制?
-
@KerrekSB 我担心这是唯一的答案。在我的 Ubuntu 12.04 工作机器上构建现代东西并让它工作并不是很有趣。
-
@KerrekSB 你能详细说明压制的东西吗?我需要为每一个错误命中都这样做吗?在我们的生产代码中,有很多,如果我必须“手动”检查所有这些,那么消毒剂就会失去意义。
-
我认为您应该能够通过代码位置进行压制。我从来没有这样做过(我写的最后一个抑制集是为 Valgrind 编写的),但请查看 wiki:github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions
标签: c++ c gcc thread-sanitizer