在本文中,我们将要学习一下如何为C/C++的ELF可执行文件剥除/添加调试信息。
示例代码
#include <iostream>
int main()
{
std::string h_w{"Hello World"};
std::cout << h_w << std::endl;
return 0;
}
操作系统:Linux
编译器:g++
编译指令:g++ test.cpp -o test -O2 -g
剥去Debug信息
步骤一:备份Debug信息和符号表
命令:objcopy --only-keep-debug test test.debug
[PerfMan@localhost test]$ ls -l
total 212
-rwxrwxr-x. 1 PerfMan PerfMan 110296 Jan 21 16:46 test
-rw-rw-r--. 1 PerfMan PerfMan 121 Jan 21 16:45 test.cpp
-rwxrwxr-x. 1 PerfMan PerfMan 98664 Jan 21 16:47 test.debug
步骤二:剥去Debug信息和符号表
命令:strip -s test 或 objcopy --strip-debug test
[PerfMan@localhost test]$ ll
total 120
-rwxrwxr-x. 1 PerfMan PerfMan 14552 Jan 21 16:47 test
-rw-rw-r--. 1 PerfMan PerfMan 121 Jan 21 16:45 test.cpp
-rwxrwxr-x. 1 PerfMan PerfMan 98664 Jan 21 16:47 test.debug
可见,剥去Debug信息和符号表后,可执行文件test相比之前变得小了很多。
步骤三:尝试调试被剥去调试信息的可执行程序
使用gdb进行调试,详情如下:
命令:(1)gdb -tui test
(2)b main
图1 调试被剥去调试信息的bin程序
从图1可知,此bin程序中已经没有调试信息了,以至于无法在main函数上设置断点,也无法看到源代码。
导入调试信息
现在,我们将要导入前文备份的调试信息文件test.debug,以达到能够正常调试的目的。
步骤一:将调试信息文件链接到可执行文件中
命令:objcopy --add-gnu-debuglink=test.debug test
步骤二:使用gdb调试可执行文件
命令:(1)gdb -tui test
(2)b main
(3)r
图2 调试导入调试信息的bin程序
从图2可知,我们已经成功地将调试信息文件test.debug中的调试信息导入到了可执行程序test中,这时就能正常地设置断点和调试了。