线程齐态(TSAN) - 共享库中有意义的信息
ThreadSanitizer (tsan) - Meaningful information from shared library
我的应用使用了WXWIDGETS库,该库是通过gcc 5.1.0构建的,使用-g和-o0
我使用clang 36 -g -fsanitize = thread -stdlib = libc 编制了我的应用程序,并使用clang 36 -g -fsanitize = thread = thread -stdlib = libc -lc abi链接它。它动态链接到WXWIDGETS。
我收到的警告之一是:
==================
WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=52741)
Cycle in lock order graph: M115 (0x7d080000ea60) => M976 (0x7d0800000100) => M115
Mutex M976 acquired here while holding mutex M115 in main thread:
#0 pthread_mutex_lock /home/xxx/sourceInstallations/llvm-3.6.0/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:3008 (wxDebugSleep+0x00000043b0ef)
#1 <null> <null> (libwx_baseu-3.0.so.0+0x0000002376fa)
#2 _start <null> (wxDebugSleep+0x00000041be4e)
Hint: use TSAN_OPTIONS=second_deadlock_stack=1 to get more informative warning message
Mutex M115 acquired here while holding mutex M976 in main thread:
#0 pthread_mutex_lock /home/xxx/sourceInstallations/llvm-3.6.0/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:3008 (wxDebugSleep+0x00000043b0ef)
#1 <null> <null> (libwx_baseu-3.0.so.0+0x0000002376fa)
#2 wxCriticalSectionLocker::wxCriticalSectionLocker(wxCriticalSection&) /usr/local/include/wx-3.0/wx/thread.h:307:9 (wxDebugSleep+0x000000473216)
#3 <null> <null> (libwx_baseu-3.0.so.0+0x00000018b297)
#4 _start <null> (wxDebugSleep+0x00000041be4e)
SUMMARY: ThreadSanitizer: lock-order-inversion (potential deadlock) ??:0 ??
==================
我不高兴,因为:(1)我想在WXWIDGETS库中找到线程错误;(2)我希望能够在一个警告与抑制文件比率或附近进行抑制文件。
因此,我从源通过clang 3.6.0重新编译/链接了WXWIDGETS库,添加-fsanitize = thread -Stdlib = libc -lc abi。交叉我的手指,完成了。
ran sudo在我的wxwidgets gcc build目录中卸载,而sudo在我的wxwidgets clang build build build目录中安装。
上面的警告现在显示:
==================
WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=68453)
Cycle in lock order graph: M115 (0x7d080000ea60) => M976 (0x7d0800000100) => M115
Mutex M976 acquired here while holding mutex M115 in main thread:
#0 pthread_mutex_lock /home/xxx/sourceInstallations/llvm-3.6.0/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:3008 (wxDebugSleep+0x00000043b0ef)
#1 <null> <null> (libwx_baseu-3.0.so.0+0x0000003c24f9)
#2 <null> <null> (libwx_baseu-3.0.so.0+0x0000003d0387)
#3 <null> <null> (libwx_baseu-3.0.so.0+0x0000003d0000)
#4 <null> <null> (libwx_baseu-3.0.so.0+0x0000001bd91c)
#5 <null> <null> (libwx_baseu-3.0.so.0+0x000000279cd6)
#6 <null> <null> (libwx_baseu-3.0.so.0+0x00000027a6da)
#7 <null> <null> (libwx_baseu-3.0.so.0+0x00000024445d)
#8 <null> <null> (libwx_baseu-3.0.so.0+0x000000244243)
#9 <null> <null> (libwx_baseu-3.0.so.0+0x000000245a67)
#10 <null> <null> (libwx_baseu-3.0.so.0+0x000000246856)
#11 <null> <null> (libwx_baseu-3.0.so.0+0x000000245430)
#12 <null> <null> (libwx_baseu-3.0.so.0+0x000000245934)
#13 main /home/xxx/code/testing/wxDebugSleep/wxDebugSleep.cpp:11:1 (wxDebugSleep+0x000000472e9c)
Hint: use TSAN_OPTIONS=second_deadlock_stack=1 to get more informative warning message
Mutex M115 acquired here while holding mutex M976 in main thread:
#0 pthread_mutex_lock /home/xxx/sourceInstallations/llvm-3.6.0/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:3008 (wxDebugSleep+0x00000043b0ef)
#1 <null> <null> (libwx_baseu-3.0.so.0+0x0000003c24f9)
#2 <null> <null> (libwx_baseu-3.0.so.0+0x0000003d0387)
#3 wxCriticalSection::Enter(void) /usr/local/include/wx-3.0/wx/thread.h:291:52 (wxDebugSleep+0x00000047c570)
#4 wxCriticalSectionLocker::wxCriticalSectionLocker(wxCriticalSection&) /usr/local/include/wx-3.0/wx/thread.h:307:9 (wxDebugSleep+0x000000473216)
#5 <null> <null> (libwx_baseu-3.0.so.0+0x000000245cf0)
#6 <null> <null> (libwx_baseu-3.0.so.0+0x000000246949)
#7 <null> <null> (libwx_baseu-3.0.so.0+0x00000024574b)
#8 <null> <null> (libwx_baseu-3.0.so.0+0x000000245934)
#9 main /home/xxx/code/testing/wxDebugSleep/wxDebugSleep.cpp:11:1 (wxDebugSleep+0x000000472e9c)
SUMMARY: ThreadSanitizer: lock-order-inversion (potential deadlock) ??:0 ??
==================
我在运行程序的环境中定义了tsan_options = second_deadlock_stack = 1,它没有更改输出。
好吧,这是一些进步。我敢肯定我要使用错误的术语,但这就像它缺少图书馆的符号文件。
我已经检查了它使用Clang&amp;-fsanitize = thread(ldd和时间戳。)
我已经检查了库是否正在使用-g和-o0编译(即使它可能更高。)
如果很重要,FreeBSD 10.1 64位。clang是从源头编译的。
问题1-如何从共享库中获取"堆栈跟踪"以显示文件名和行号?
问题2-如果我不能,如何制作一个好的抑制文件?问题在于WXWIDGETS调用了很多我的代码,因此我认为我无法阻止包括库在内的任何堆栈。而且,当然,即使我可以使用偏移来制作抑制文件,如果我重新编译了库,所有这些都可以更改。
问题是FreeBSD 10.1及以前有一个错误,从而阻止LLVM-Symbolizer正常工作。LLVM-Symbolizer是TSAN获取符号信息的方式。更具体地说,FreeBSD在没有DL_ITERATE_PHDR中的路径的情况下给出了DLPI_NAME。这是在https://reviews.freebsd.org/d932上修补的。该补丁可在freebsd 10稳定中使用(此答案时,就像10.2 beta),应在freebsd 10.2及以后。
。btw," -wl, - 版本 - script ..."answers" -wl,-soname"工作正常。
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 在c++中,如果首先禁止默认构造,那么禁止复制构造有意义吗
- sizeof(函数)有意义吗?
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 在 C++17 中使用 const std::string& 参数有意义吗?
- 基础类模板参数的有意义名称
- 内联这个函数,确实有意义
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 是否有一个上下文表达式`a.b :: c`有意义
- 是否有一些有意义的统计数据来证明保持有符号整数算术溢出未定义是合理的
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 将 [[noreturn]] 添加到主函数是否有意义
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?
- YAML-CPP 节点诊断有意义的错误
- 线程齐态(TSAN) - 共享库中有意义的信息