在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
    内部
    foo.o
    (a1)的地址(从上面的
    nm
    输出)
  • foo.o
    .text
    的地址(a2,使用
    readelf-WS foo.o | grep'\.text$)
  • 主二进制文件中
    foo
    的地址(a3,使用
    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我已经更新了位置独立可执行文件的答案——在这种情况下,需要添加一个额外的重新定位。