在gdb中调试发行版(不带符号),但使用源生成文件夹(.o文件)?
我从源代码中构建了一个应用程序,它在大多数情况下都工作得很好,但对于我最近遇到的某个问题,它保证了调试程序的运行 然而,问题是构建需要一个小时或更长时间,我已经在发行版中构建了这个应用程序,意思是在gdb中调试发行版(不带符号),但使用源生成文件夹(.o文件)?,gdb,Gdb,我从源代码中构建了一个应用程序,它在大多数情况下都工作得很好,但对于我最近遇到的某个问题,它保证了调试程序的运行 然而,问题是构建需要一个小时或更长时间,我已经在发行版中构建了这个应用程序,意思是gdb说“(没有找到调试符号)…完成了。” 我仍然可以使用可执行文件原样在gdb中设置函数断点,但我不能单步执行代码(“单步执行直到退出函数…,它没有行号信息;找不到当前函数的边界”) 因此,考虑到我有源代码和一个充满.o文件的源代码构建文件夹,-为了不必在构建调试版本上浪费可能的几个小时,-我想知道是
gdb
说“(没有找到调试符号)…完成了。”
我仍然可以使用可执行文件原样在gdb
中设置函数断点,但我不能单步执行代码(“单步执行直到退出函数…,它没有行号信息;找不到当前函数的边界”)
因此,考虑到我有源代码和一个充满.o
文件的源代码构建文件夹,-为了不必在构建调试版本上浪费可能的几个小时,-我想知道是否有可能以某种方式指示gdb
使用这些文件/目录,然后让我逐步完成代码
我想知道是否有可能以某种方式指示gdb使用这些文件/目录,然后让我逐步完成代码
对
首先,您需要准备要逐步执行的函数的匹配副本,但要包含调试信息
假设在foo.o
和bar.o
中分别有foo()
和bar()
。您需要使用所有原始标志重新构建它们,并添加-g
:
rm -f foo.o bar.o
make foo.o bar.o CFLAGS="$ORIGINAL_FLAGS -g"
接下来,您需要找出foo()
和bar()
的位置:
nm -A foo.o bar.o | egrep ' (foo|bar)$'
最后,您需要使用GDB添加符号文件foo.o$ADDR\u foo\u o
和添加符号文件bar.o$ADDR\u bar\u o
来享受源代码调试的乐趣
计算$ADDR\u foo\u o
有点棘手:您需要
内部foo
(a1)的地址(从上面的foo.o
输出)nm
中foo.o
的地址(a2,使用.text
readelf-WS foo.o | grep'\.text$)
- 主二进制文件中
的地址(a3,使用foo
)nm a.out | grep'foo$”
$ADDR\u foo\o=$a3-$a1+$a2
对于位置独立的可执行文件,您还需要添加a.out
relocation(a4),您可以从info file
或info proc mappings
中找到它
另外,为了避免这种痛苦,您应该始终使用
-g
标志(与优化标志正交)构建发行版二进制文件,并使用strip-ga.out-oa.out-for-deployment
。然后保留a.out
进行调试,并将剥离版本部署到生产/客户。您应该使用单独的调试文件创建发布版本。看一看啊,这太棒了,非常感谢-仍在重建中,但我不需要重建整个源代码:)
。再次感谢@SDAU我已经更新了位置独立可执行文件的答案——在这种情况下,需要添加一个额外的重新定位。