assembly GDB不从NASM加载源代码行

llycmphe  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(143)

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

nasm -f elf64 -g -F dwarf -o foo.o foo.asm
ld -o foo foo.o

资料来源:

section .text
    global _start
_start:
    mov rax, 60     ;SYS_exit
    mov rdi, 0      ;EXIT_SUCCESS
    syscall

用GDB调试程序并不显示指令来自哪个文件或行号。例如,break _start显示“断点1在0x 401000”而不是“断点1在0x 400080:file foo.asm,line 4.”,如blog post中所示。切换到layout regs会显示“No Source Available”,而不是在源代码中找到当前指令的位置。list确实会显示源代码,但在单步执行下一条指令时会切换回“No Source Available”。
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

Ubuntu 22.04、NASM 2.15.05、GDB 12.09版本

6ie5vjzr

6ie5vjzr1#

我安装了一个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

下面是损坏的可执行文件中的相同部分:

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

关键的区别是DW_AT_high_pc,这似乎是2.15.05 nasm的错误。我手动编辑了这个值,突然之间,我可以调试以前损坏的可执行文件了。
这似乎是nasm的2.15.05中的一个回归,您应该考虑降级nasm(我认为2.15.05是当前的最新版本),或者可能提交一个nasm bug。

w1jd8yoj

w1jd8yoj2#

正如Andrew所指出的,这确实是nasm(https://bugzilla.nasm.us/show_bug.cgi?id=3392798)中的一个bug。它不会通过降级来修复,因为据我所知,这个bug已经很老了。
这个bug现在已经很明显了,因为旧版本的GNU ld有一个问题补充了这个问题(使它不易察觉)。
好的部分是,我已经发送了一个非常简单和小的补丁(我觉得很舒服的想法是正确的阅读后,通过ld-nasm的互动和为什么它没有被发现之前)。
如果您想阅读该补丁(如果您发现问题,甚至可以留下有用的评论),请访问:https://github.com/netwide-assembler/nasm/pull/35
此外,如果你使用Ubuntu 22.04,我已经构建了一个补丁.deb,它应该相对容易安装https://github.com/iglosiggio/nasm/releases/tag/nasm-2.15.05-2

ybzsozfc

ybzsozfc3#

IIRC,GDB可以很好地使用NASM的默认STABS输出,所以让它使用它来代替DWARF。Jester说GNU工具使用了一种新的DWARF格式,NASM不知道如何制作。但是它们仍然支持被DWARF取代的STABS格式。STABS对于Map源代码行到地址的简单任务来说非常好,这是像NASM这样简单的源代码语言所需要的全部。
只需使用不带-F选项的nasm -g即可。
或者也可以省略-g,您仍然可以得到符号名,而且除了基本的标签名之外,我在手工编写的asm中对调试信息没有太多的用处。(当然,节头文件也不需要在可执行文件中使用,只需要程序头文件。如果您尝试在FASM直接创建的可执行文件上使用GDB,您就会发现这一点。)
我总是在layout reg之后使用layout n,来切换到寄存器+反汇编。我不确定当前的行为是否是GDB的bug或什么。(在一些以前的版本中,layout next/prev都是必需的,就像它认为配置设置与UI实际显示的内容不同步一样)。
无论如何,我基本上不希望GDB显示.asm源代码,我希望它显示我正在运行的任何东西的规范反汇编,以防我写的东西与它看起来不同。
在asm源代码中使用有意义的标签名称将导致GDB显示以sieve.crossout或其他方式执行。尽管这对于大量的条件分支来说不太好,因为每个分支目标看起来都像是GDB的完整标签。

相关问题