我已经从源代码构建了一个应用程序,该应用程序在很大程度上可以正常工作,但是对于我最近遇到的某些问题,它值得您调试一下。
但是,问题在于构建需要一个小时或更长时间,并且我已经在发行版中构建了该应用程序,这意味着gdb
表示“(未找到调试符号)...完成。”。 / p>
我仍然可以按原样使用可执行文件在gdb
中设置函数断点,除了我无法单步执行代码(“单步执行,直到从函数...退出,它没有行号信息。;找不到边界)。当前功能”)。
因此,鉴于我有一个充满.o
文件的源代码和一个源代码构建文件夹,-为了不必在构建调试版本上浪费很多时间,我想知道是否有可能以某种方式指示gdb
使用这些文件/目录,然后让我逐步执行代码?
答案 0 :(得分:1)
我想知道是否可以通过某种方式指示gdb使用这些文件/目录,然后让我逐步执行代码?
是的
首先,您需要准备要逐步执行的功能的 matching 副本,但要包含调试信息。
假设您在foo()
和bar()
中分别有foo.o
和bar.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_o
和add-symbol-file bar.o $ADDR_bar_o
来进行源调试。
计算$ADDR_foo_o
有点棘手:您需要
foo
(a1)内foo.o
的地址(上述nm
的输出),.text
中foo.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 file
或info proc mappings
中找到。
P.S。为了避免这种麻烦,您应该始终使用-g
标志(与优化标志正交)构建发布二进制文件,并使用strip -g a.out -o a.out-for-deployment
。然后保留a.out
进行调试,然后将剥离后的版本部署到生产/客户。