linux - AddressSanitizer:分离调试信息后报告中没有匹配的源文件行
问题描述
- CentOS Linux 发行版 7.6.1810(核心)
- g++ (GCC) 6.5.0
- libasan3-6.3.1-3.1.el6.x86_64
我正在使用 AddressSanitizer 来检测内存错误。与常见情况不同,我需要构建一个 rpm 包,而不是编译源代码并直接运行它。我有下面的测试代码:
#include <iostream>
#include <string.h>
using namespace std;
//void test3(char*) __attribute__((no_sanitize_address));
//__attribute__((no_sanitize_address))
void test3(char *p){
delete[] p;
cout << *p << endl;
cout << "test3" << endl;
}
//__attribute__((no_sanitize_address))
void test2(char *ptr, char *p){
if(memcmp(ptr,p,6) == 0){
cout << "Yes" << endl;
}
cout << "test2" << endl;
}
int main(){
char *p = new char[5];
char *ptr = new char[6];
test2(ptr, p);
test3(p);
delete[] ptr;
return 0;
}
编译标志是-fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=address -g -pipe -rdynamic -Wl,--build-id
. 然后我rpmbuild
用来构建下面的rpm包:
Wrote: /root/rpmbuild/RPMS/x86_64/main_test-1.0.0-1.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/main_test-debuginfo-1.0.0-1.x86_64.rpm
安装main_test
and后main_test-debuginfo
,我运行main
. 现在的问题是 Asan 没有报告任何源文件行。
=================================================================
==39137==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff5 at pc 0x7ffff6ecd328 bp 0x7fffffffe350 sp 0x7fffffffdb00
READ of size 6 at 0x60200000eff5 thread T0
#0 0x7ffff6ecd327 (/usr/lib64/libasan.so.3+0x8d327)
#1 0x400ee2 in test2(char*, char*) (/usr/local/bin/main+0x400ee2)
#2 0x400f58 in main (/usr/local/bin/main+0x400f58)
#3 0x7ffff62763d4 in __libc_start_main (/usr/lib64/libc.so.6+0x223d4)
#4 0x400d58 (/usr/local/bin/main+0x400d58)
0x60200000eff5 is located 0 bytes to the right of 5-byte region [0x60200000eff0,0x60200000eff5)
allocated by thread T0 here:
#0 0x7ffff6f02e70 in operator new[](unsigned long) (/usr/lib64/libasan.so.3+0xc2e70)
#1 0x400f33 in main (/usr/local/bin/main+0x400f33)
#2 0x7ffff62763d4 in __libc_start_main (/usr/lib64/libc.so.6+0x223d4)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib64/libasan.so.3+0x8d327)
...
然而,期望是:
=================================================================
==36210==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff5 at pc 0x7ffff6ecd328 bp 0x7fffffffe370 sp 0x7fffffffdb20
READ of size 6 at 0x60200000eff5 thread T0
#0 0x7ffff6ecd327 (/usr/lib64/libasan.so.3+0x8d327)
#1 0x400ee2 in test2(char*, char*) /home/matt/main_test-1.0.0/main.cpp:17
#2 0x400f58 in main /home/matt/main_test-1.0.0/main.cpp:27
#3 0x7ffff62763d4 in __libc_start_main (/usr/lib64/libc.so.6+0x223d4)
#4 0x400d58 (/home/matt/main_test-1.0.0/main+0x400d58)
0x60200000eff5 is located 0 bytes to the right of 5-byte region [0x60200000eff0,0x60200000eff5)
allocated by thread T0 here:
#0 0x7ffff6f02e70 in operator new[](unsigned long) (/usr/lib64/libasan.so.3+0xc2e70)
#1 0x400f33 in main /home/matt/main_test-1.0.0/main.cpp:24
#2 0x7ffff62763d4 in __libc_start_main (/usr/lib64/libc.so.6+0x223d4)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib64/libasan.so.3+0x8d327)
...
Asan 似乎无法链接源文件。我对出了什么问题感到困惑。有什么办法可以解决吗?
感谢你!
解决方案
我对出了什么问题感到困惑。
AddressSanitizer 运行时可能未设置为使用单独的调试信息。
[更新: @fche 评论说 asan/libbacktrace 工具在 gcc 10.1 左右获得了单独的调试信息支持]
没有根本原因它不能,但这不是大多数开发人员使用 AddressSanitizer 的方式。
有什么办法可以解决吗?
你有几个选择:
- 在.
strip
_ 这个答案可能有用。rpmbuild
- 用于
addr2line -fe /path/to/unstripped/binary 0x400ee2 0x400f58 ...
事后恢复源文件/行信息。
推荐阅读
- c# - 数据编辑窗口中收集列表中的绑定数据问题
- angular - 订阅 BehaviorSubject 直到值未定义
- c# - 如果我有一个逗号分隔的字符串,如何过滤值
- bash - 将 [nameref] 声明为指向函数的指针,失败
- swift - 将变量从 UIPageViewController 传递给 UIViewController 子
- javascript - 匹配不带小数且大于 10,000 的数字
- javascript - 如何检查文本框值是否在特定范围内
- javascript - 在 reactJS 中触发 onClick 函数后如何进入初始状态?
- regex - 是否有从 Google 表格中的框中提取特定字符的公式?
- angular - 谷歌图表:在柱形图中显示轴的末端或轴的顶部