2

我正在尝试自动化一些调试任务。在某些情况下,我将$ra[this is a MIPS machine] 的值和堆栈的一部分打印为十六进制地址。在调试期间,我使用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在文件中看到的完整路径。我怎样才能以编程方式得到这个?

谢谢。

4

1 回答 1

1

这是非常令人惊讶的行为。我无法在以下位置重现它:

  • 带有 gcc 4.1.2 和 addr2line 2.17.50.0.6 的 Linux

  • Cygwin 与 gcc 4.3.4 和 gcc 3.4.4 和 addr2line 2.20.51.20100410

addr2line 应该依赖于存储在可执行文件中的调试信息。并且调试信息应该包含绝对路径(无论给编译器的源路径是什么),以避免在使用调试器时出现任何歧义。无论我在哪里尝试,addr2line 总是显示绝对路径。

假设您正在为您的构建系统使用 make,一个选项,尽管可能是一个痛苦的选项,将更改您的 makefile 以使用非递归策略(无论如何您确实应该这样做)。在这样的系统中,只有一个 make 实例正在运行,来自一个工作目录(通常是源代码树的顶层)。因此,编译器的所有调用都指定了源文件的完整路径(相对于源树的根)。实际上,如果 addr2line 始终显示为编译器指定的文件名,这将解决您的问题。不是最好的解决方案,但可行的解决方案。作为附带的好处,您将获得非递归 make 的所有优点。

于 2010-07-30T14:28:49.793 回答