GDB 不从 NASM 加载源代码行

Joe*_*ard 9 assembly gdb x86-64 nasm

我正在 Ubuntu 上使用 NASM 组装 x86-64 程序:

nasm -f elf64 -g -F dwarf -o foo.o foo.asm
ld -o foo foo.o
Run Code Online (Sandbox Code Playgroud)

来源:

section .text
    global _start
_start:
    mov rax, 60     ;SYS_exit
    mov rdi, 0      ;EXIT_SUCCESS
    syscall
Run Code Online (Sandbox Code Playgroud)

使用 GDB 调试程序不会显示指令来自哪个文件或行号。例如,break _start显示“断点 1 at 0x401000”而不是“断点 1 at 0x400080:文件 foo.asm,第 4 行”。如这篇博文所示。切换到layout regs显示“无可用源”,而不是在源中找到当前指令的位置。list确实显示了源,但在进入下一条指令时它会切换回“无可用源”。

objdump -g foo似乎表明所需的调试信息就在那里:

foo:     file format elf64-x86-64
...
The File Name Table (offset 0x1c):
  Entry Dir     Time    Size    Name
  1     0       0       0       foo.asm

 Line Number Statements:
  [0x00000028]  Extended opcode 2: set Address to 0x401000
  [0x00000033]  Special opcode 8: advance Address by 0 to 0x401000 and Line by 3 to 4
  [0x00000034]  Special opcode 76: advance Address by 5 to 0x401005 and Line by 1 to 5
  [0x00000035]  Special opcode 76: advance Address by 5 to 0x40100a and Line by 1 to 6
  [0x00000036]  Advance PC by 2 to 0x40100c
  [0x00000038]  Extended opcode 1: End of Sequence
Run Code Online (Sandbox Code Playgroud)

Ubuntu 22.04、NASM 2.15.05、GDB 12.09

And*_*rew 6

我设置了一个 Ubuntu 22.04 VM,发现我可以重现您在那里看到的问题,但是,在我的本地计算机上,我无法重现该问题。

我注意到在我的本地计算机上我使用的是 nasm 2.14.02,而在 Ubuntu 计算机上我使用的是 2.15.05。

如果我们检查objdump -g两个可执行文件的输出,以下是我从工作可执行文件中看到的部分内容:

Contents of the .debug_info section (loaded from foo):

  Compilation Unit @ offset 0x0:
   Length:        0x45 (32-bit)
   Version:       3
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_low_pc      : 0x401000
    <14>   DW_AT_high_pc     : 0x40100c
    <1c>   DW_AT_stmt_list   : 0x0
    <20>   DW_AT_name        : foo.asm
    <28>   DW_AT_producer    : NASM 2.14.02
    <35>   DW_AT_language    : 32769    (MIPS assembler)
 <1><37>: Abbrev Number: 2 (DW_TAG_subprogram)
    <38>   DW_AT_low_pc      : 0x401000
    <40>   DW_AT_frame_base  : 0x0 (location list)
 <1><44>: Abbrev Number: 0
Run Code Online (Sandbox Code Playgroud)

这是损坏的可执行文件的相同部分:

Contents of the .debug_info section (loaded from foo):

  Compilation Unit @ offset 0x0:
   Length:        0x45 (32-bit)
   Version:       3
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_low_pc      : 0x401000
    <14>   DW_AT_high_pc     : 0x401000
    <1c>   DW_AT_stmt_list   : 0x0
    <20>   DW_AT_name        : foo.asm
    <28>   DW_AT_producer    : NASM 2.15.05
    <35>   DW_AT_language    : 32769    (MIPS assembler)
 <1><37>: Abbrev Number: 2 (DW_TAG_subprogram)
    <38>   DW_AT_low_pc      : 0x401000
    <40>   DW_AT_frame_base  : 0x0 (location list)
 <1><44>: Abbrev Number: 0
Run Code Online (Sandbox Code Playgroud)

关键的区别是DW_AT_high_pc,这对于 2.15.05 nasm 来说似乎是错误的。我手动进入并编辑了这个值,突然间,我可以很好地调试之前损坏的可执行文件。

这似乎是 nasm 2.15.05 中的回归,您应该考虑降级 nasm(我认为 2.15.05 是当前最新版本),或者可能提交 nasm bug。