我正在尝试自动执行一些调试任务。在某些情况下,我打印$ra
[这是一个MIPS机器]的值,并将堆栈的一部分打印为十六进制地址。在调试过程中,我使用addr2line
将它们转换为file:line
对。
我想自动执行此程序。
问题是addr2line在编译时返回的文件名与__FILE__
的值相等;即传递给编译器的文件名。通常为foo.c
,有时为src/foo.c
。由于我的项目总共有几百个目录,这可能不足以唯一地标识文件(可能有1/foo.c
,2/foo.c
等)。即使它是确定性的,在我的屏幕上为每个参数开始运行find似乎相当低效[我想我可以构建一个哈希表并保存它们,但我想将它保存为一个简单的bash脚本]
GDB似乎得到了正确的文件。如果我查看带有调试符号的实际源文件,我还可以看到文件名后面似乎是__FILE__
的完整路径[即,如果__FILE__
是src/foo.c
,它真的在/home/me/projects/something/comp1/src/foo.c
,我会在文件中看到/home/me/projects/something/comp1
。我怎样才能得到这个进步?
感谢。
答案 0 :(得分:1)
这是非常令人惊讶的行为。我无法重现它:
Linux with gcc 4.1.2 and addr2line 2.17.50.0.6
Cygwin与gcc 4.3.4和gcc 3.4.4和addr2line 2.20.51.20100410
addr2line应该依赖存储在可执行文件中的调试信息。并且调试信息应该包含绝对路径(无论给编译器提供什么源路径),以避免在使用调试器时出现任何歧义。无论我在哪里尝试,addr2line总会显示绝对路径。
假设你正在为你的构建系统使用make,一个选项,虽然可能是一个痛苦的选择,但是会改变你的makefile以使用非递归策略(无论如何你应该做的事情)。使用这样的系统,从单个工作目录(通常是源树的顶层)只运行一个make实例。因此,编译器的所有调用都指定源文件的完整路径(相对于源树的根)。如果事实上addr2line总是显示为编译器指定的文件名,这将解决您的问题。不是最好的解决方案,而是一个可行的解决方案。作为附带好处,您将获得非递归制作的所有优势。