【问题标题】:Linux (64-bit), nasm and gdbLinux(64 位)、nasm 和 gdb
【发布时间】:2011-11-19 19:30:07
【问题描述】:

我在搜索其他线程时运气不佳。 我的问题可能很简单但令人沮丧。 我正在 64 位 Ubuntu 11.04 上编译两个文件:

  1. nasm -f elf64 -g file64.asm
  2. gcc -g -o file file.c file64.o

然后我使用 gdb 调试生成的可执行文件。 使用 C,一切正常。 但是,在调试程序集时,源代码对调试器“不可见”。我得到以下输出:

(gdb) step
Single stepping until exit from function line,
which has no line number information.
0x0000000000400962 in convert ()

快速调查:

objdump --source file64.o

表明汇编源代码(和行信息)包含在文件中。

为什么我在调试会话中看不到它?我究竟做错了什么? 这些问题是在迁移到 64 位 Ubuntu 后出现的。在 32 位 Linux 中它可以工作(应该如此)。

【问题讨论】:

  • 不知道是否有帮助,但您是否尝试过明确指定 nasm 的调试格式?例如。 nasm -f elf64 -F stabs -g file64.asm
  • 不,Dmitri,不幸的是它没有帮助。还是一样的情况,谢谢你的回复
  • 我做了一个实验。我在 32 位版本的 Ubuntu(我也有)下构建了 64 位目标文件(file64.o)并在 64 位系统下链接它,现在它可以工作了(!)但是 nasm 的调用总是相同的:nasm -f elf64 -g file64.asm 我一直以同样的方式使用 gdb。看起来问题出在 64 位版本的 nasm 中(我猜)

标签: linux gdb nasm


【解决方案1】:

对于其他在 NASM 上遇到问题的人(该错误尚未修复):只需下载 NASM git 存储库并切换到版本 2.7,这可能是最后一个可以正常工作的版本,即支持 gdb。从源代码构建这个过时的版本只是一种解决方法(例如,您不支持最后一个 ISA),但对于大多数学生来说已经足够了。

【讨论】:

    【解决方案2】:

    使用 NASM,在使用 dwarf 调试格式时,我在 gdb 方面的体验要好得多。然后 gdb 将汇编源代码视为任何其他语言(即不需要反汇编命令)

    nasm -f elf64 -g -F dwarf file64.asm
    

    (如果指定了-F,2.03.01 及更高版本会自动启用-g。)

    我使用的是 NASM 版本 2.10.07。我不确定这是否会有所不同。

    【讨论】:

    • 我可以确认我用 -gdwarf 解决了同样的问题
    【解决方案3】:

    GDB 可能不知道在哪里搜索您的源文件。尝试用directory 明确告诉它。

    【讨论】:

      【解决方案4】:

      GDB 是一个源代码级(或符号)调试器,这意味着它应该使用“高级编程语言”......这不是你的情况!

      但请稍等,因为从调试器的角度来看,调试 ASM 程序比高级语言容易得多:几乎无事可做!程序二进制总是包含汇编指令,只是用它们的机器格式编写,而不是ascii格式。

      GDB 有能力为你转换它。不用执行list查看代码,而是使用disassemble查看函数代码:

      (gdb) disassemble <your symbol>
      Dump of assembler code for function <your symbol>:
         0x000000000040051e <+0>: push   %rbp
         0x000000000040051f <+1>: mov    %rsp,%rbp
      => 0x0000000000400522 <+4>: mov    0x20042f(%rip),%rax        
         0x0000000000400529 <+11>:    mov    %rax,%rdx
         0x000000000040052c <+14>:    mov    $0x400678,%eax
         0x0000000000400531 <+19>:    mov    %rdx,%rcx
      

      x/5i $pc 在您的$pc

      之后查看5 i指令
      (gdb) x/5i $pc
      => 0x400522 <main+4>:   mov    0x20042f(%rip),%rax
         0x400529 <main+11>:  mov    %rax,%rdx
         0x40052c <main+14>:  mov    $0x400678,%eax
         0x400531 <main+19>:  mov    %rdx,%rcx
         0x400534 <main+22>:  mov    $0xc,%edx
      

      然后使用stepi (si) 插入stepnexti (ni) 而不是next

      display $pc 也可以用于在下级停止时打印当前的pc(即,在每个nexti/stepi 之后。

      【讨论】:

      • 没有。如果代码是用汇编编写的,那么简单就是要显示的源代码。 GDB 并不关心所讨论的语言是否被认为是高级语言。
      • @Fabel 我不确定你的评论是否理解,你对什么说“不”? disassemble' and stepi` 不起作用?
      • 我认为答案给人的印象是 disassemble/stepi 是调试用汇编编写的代码的唯一(或至少首选)方法。这就是我不同意的。如果源代码可用,GDB 可以像使用高级语言的源代码一样使用它,这是一种更简单的方法。
      • @Fabel 是的,你是对的,原始源代码可能/将包含比disassemble 打印的更多信息。假设我的解决方案是一种始终有效的解决方法,尽管 OP 的环境中仍然存在问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多