【问题标题】:How can I use gdb to debug code assembled using yasm?如何使用 gdb 调试使用 yasm 组装的代码?
【发布时间】:2014-12-22 02:26:36
【问题描述】:

我已使用 yasm 进行代码汇编,并链接到我的 C++ 程序,但我无法在 gdb 中对汇编语言文件中的符号设置断点。

命令行可能不是非常有启发性,但我们开始吧:

"g++"  -ftemplate-depth-128 -O0 -fno-inline -Wall -g -fPIC -std=c++11   -I"$HOME/usr/include" -c -o "bin/gcc-4.7/debug/main.o" "main.cpp"
yasm -g dwarf2 -f elf64 -o bin/gcc-4.7/debug/mandel.o mandel.yasm
"g++" -L"$HOME/usr/lib" -Wl,-R -Wl,"$HOME/usr/lib" -Wl,-rpath-link -Wl,"$HOME/usr/lib" -o "bin/gcc-4.7/debug/mandel" -Wl,--start-group "bin/gcc-4.7/debug/main.o" "bin/gcc-4.7/debug/mandel.o"  -Wl,-Bstatic  -Wl,-Bdynamic -lboost_system -lboost_thread -Wl,--end-group -g 

一切顺利,程序运行。但是当我尝试将它加载到 gdb 中进行调试时,我似乎无法在 yasm 文件中的任何函数上放置断点。例如,我在那里有一个名为 MandelRect 的函数。这是 gdb 向我展示了它是从哪里调用的,在 main 的某个地方:

(gdb) disassemble 0x404ada,0x404af0
Dump of assembler code from 0x404ada to 0x404af0:
   0x0000000000404ada <main()+474>:     mov    %rax,%rdi
   0x0000000000404add <main()+477>:     callq  0x409980 <MandelRect>
   0x0000000000404ae2 <main()+482>:     movq   $0x0,-0x18(%rbp)
   0x0000000000404aea <main()+490>:     jmp    0x404b1c <main()+540>
   0x0000000000404aec <main()+492>:     mov    -0x18(%rbp),%rdx
End of assembler dump.

这里的 gdb 向我展示了它的地址:

(gdb) info address MandelRect
Symbol "MandelRect" is at 0x409980 in a file compiled without debugging.

这是 gdb 无法在其上设置断点:

(gdb) break MandelRect
Function "MandelRect" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n

如果我在正确的地址设置断点,当执行到达函数时,我无法逐条执行它。据我所知,它只是从一个标签到另一个标签。

显然 - 好吧,也许? - 这与 gdb 坚持该文件是在没有调试的情况下编译的有关。但在相关的 .o 文件和二进制文件中似乎确实存在符号:

~/tests/mandel/bin/gcc-4.7/debug% nm mandel.o | grep MandelRectAsm
0000000000000000 R MandelRectAsm
~/tests/mandel/bin/gcc-4.7/debug% nm mandel | grep MandelRectAsm 
000000000040a340 R MandelRectAsm
~/tests/mandel/bin/gcc-4.7/debug% objdump -t mandel.o | grep -i MandelRectAsm
0000000000000000 g       .txt   0000000000000000 MandelRectAsm
~/tests/mandel/bin/gcc-4.7/debug% objdump -t mandel | grep -i MandelRectAsm
000000000040a340 g       .txt   0000000000000000              MandelRectAsm

那么我该如何解决这个问题?我误解了什么,还是yasm -g 坏了?有没有人设法让 yasm 的调试信息与 gdb 一起工作?

(系统为Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 GNU/Linux。)

【问题讨论】:

  • 我会在 mandel.o 和 madel 上尝试 nm 和 objdump -g 来查看调试信息在哪里丢失/损坏。
  • 感谢您的建议。我已经更新了这个问题。 objdump -g 没有为我尝试过的任何文件打印任何内容(例如,实际上什么都没有,只是说文件是 elf64-x86-64)所以我改用了 objdump -t。跨度>

标签: c++ linux gdb dwarf yasm


【解决方案1】:

我的程序包含.text 部分之外的代码,因为我设法在 asm 文件中拼错了“文本”(如您在上面的 objdump 输出中所见)。 yasm 让您可以随意命名您的部分,显然它们最终会被标记为可执行文件,但显然许多工具并没有预料到这一点......

这也修复了我从 perf 得到的一些奇怪结果。

【讨论】:

    猜你喜欢
    • 2013-01-07
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2014-04-24
    • 2013-09-29
    相关资源
    最近更新 更多