在gdb中调试版本(无符号),但具有源构建文件夹(.o文件)?

时间:2018-12-20 05:09:27

标签: gdb

我已经从源代码构建了一个应用程序,该应用程序在很大程度上可以正常工作,但是对于我最近遇到的某些问题,它值得您调试一下。

但是,问题在于构建需要一个小时或更长时间,并且我已经在发行版中构建了该应用程序,这意味着gdb表示“(未找到调试符号)...完成。”。 / p>

我仍然可以按原样使用可执行文件在gdb中设置函数断点,除了我无法单步执行代码(“单步执行,直到从函数...退出,它没有行号信息。;找不到边界)。当前功能”)。

因此,鉴于我有一个充满.o文件的源代码和一个源代码构建文件夹,-为了不必在构建调试版本上浪费很多时间,我想知道是否有可能以某种方式指示gdb使用这些文件/目录,然后让我逐步执行代码?

1 个答案:

答案 0 :(得分:1)

  

我想知道是否可以通过某种方式指示gdb使用这些文件/目录,然后让我逐步执行代码?

是的

首先,您需要准备要逐步执行的功能的 matching 副本,但要包含调试信息。

假设您在foo()bar()中分别有foo.obar.o。您需要使用所有原始标志重建它们,并添加-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 add-symbol-file foo.o $ADDR_foo_oadd-symbol-file bar.o $ADDR_bar_o来进行源调试。

计算$ADDR_foo_o有点棘手:您需要

  • foo(a1)内foo.o的地址(上述nm的输出),
  • .textfoo.o的地址(a2,使用readelf -WS foo.o | grep '\.text$'),
  • 主二进制文件中foo的地址(a3,使用nm a.out | grep ' foo$')。

我相信您需要$ADDR_foo_o = $a3 - $a1 + $a2

对于与位置无关的可执行文件,您还需要添加a.out重定位(a4),可从info fileinfo proc mappings中找到。

P.S。为了避免这种麻烦,您应该始终使用-g标志(与优化标志正交)构建发布二进制文件,并使用strip -g a.out -o a.out-for-deployment。然后保留a.out进行调试,然后将剥离后的版本部署到生产/客户。