Ubuntu下TSAN无法解析动态加载SO符号的问题求助
环境信息
- 系统:Ubuntu 20.04.2
- 编译器:g++ 9.4.0
- 工具:ThreadSanitizer (TSAN)
问题现象
TSAN能够解析主可执行文件的符号,但无法解析动态加载的SO文件中的符号,警告输出中出现<null>占位符,无法看到完整调用栈:
WARNING: ThreadSanitizer: data race (pid=58921)
Read of size 8 at 0x7b4000000800 by thread T1:
#0 memchr ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:915 (libtsan.so.0+0x36f6f)
#1 memchr ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:911 (libtsan.so.0+0x36f6f)
#2 std::__cxx11::basic_string<char, std::char_traits, std::allocator >::find(char const*, unsigned long, unsigned long) const (libstdc++.so.6+0x144f44) Previous write of size 8 at 0x7b4000000800 by main thread (mutexes: write M17):
#0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.0+0x8c032)
#1 void std::__cxx11::basic_string<char, std::char_traits, std::allocator >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) /usr/include/c++/9/bits/basic_string.tcc:219 (libcyber_Scommon_Slibfile.so+0x709d)
#2(libplanner_common.so+0x70e340)
#3(libplanner_runner.so+0x38b3b2)
#4(libplanner_component.so+0x4d40e)
#5(libplanner_component.so+0x98f4f)
#6 apollo::cyber::TimerComponent::Initialize(apollo::cyber::proto::TimerComponentConfig const&) cyber/component/timer_component.cc:42 (libcyber_Scomponent_Slibtimer_Ucomponent.so+0x3e78)
解决方案步骤
1. 编译SO文件时保留调试符号
编译动态库时,必须添加-g参数保留调试信息,同时配合TSAN的编译参数:
g++ -g -fsanitize=thread -shared -fPIC -o libplanner_common.so your_source_files.cpp
注意:所有涉及的动态库都需要用相同参数编译,确保TSAN能识别符号。
2. 确保TSAN能找到SO文件的调试符号
如果SO文件不在默认路径,运行程序前设置LD_LIBRARY_PATH指定库路径:
export LD_LIBRARY_PATH=/path/to/your/so/files:$LD_LIBRARY_PATH
3. 手动解析缺失的符号
如果运行后仍出现<null>,可以用addr2line工具手动解析地址:
addr2line -e libplanner_common.so 0x70e340
将命令中的libplanner_common.so和地址替换为警告中对应的库和偏移量,即可得到具体的函数和行号。
4. 启用TSAN的符号解析选项
运行程序时添加TSAN_OPTIONS=symbolize=1环境变量,强制TSAN进行符号解析:
TSAN_OPTIONS=symbolize=1 ./your_executable
5. 检查libstdc++的符号支持
对于libstdc++的符号缺失,确保安装了对应的调试包:
sudo apt-get install libstdc++6-dbg
内容的提问来源于stack exchange,提问作者ShowCode

