代码之家  ›  专栏  ›  技术社区  ›  Mikeage

从addr2行获取完整路径

  •  2
  • Mikeage  · 技术社区  · 14 年前

    我正在尝试自动化一些调试任务。在某些情况下,我会打印 $ra [这是一台MIPS机器]和作为十六进制地址的堆栈部分。在调试期间,我使用 addr2line 把它们变成 file:line 对。

    我想使这个过程自动化。

    问题是addr2line返回的文件名等于 __FILE__ 编译时,即传递给编译器的文件名。这通常是 foo.c ,有时 src/foo.c . 由于我的项目总共有几百个目录,这可能不足以唯一地标识文件(可能 1/foo.c , 2/foo.c 等)。即使它是确定性的,在我的屏幕上为每个参数运行find似乎也相当低效[我想我可以构建一个哈希表并保存它们,但我想将其作为一个简单的bash脚本保存]

    gdb似乎得到了正确的文件。如果我查看带有调试符号的实际源文件,我还可以看到在文件名后面似乎有指向 一个文件 [即,如果 一个文件 SRC/FoO.C 而且它真的在 /home/me/projects/something/comp1/src/foo.c 我会看到 /home/me/projects/something/comp1 在文件中。我怎样才能通过程序得到这个?

    谢谢。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Dan Moulding    14 年前

    这是非常令人惊讶的行为。我无法复制它:

    • 带GCC 4.1.2和addr2line 2.17.50.0.6的Linux

    • Cygwin,GCC 4.3.4和GCC 3.4.4以及Addr2线路2.20.51.20100410

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

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