使用 gdb 调试 NASM 本地标签

问题描述

我在调试由 nasmgdb 组装的代码时遇到了一些问题:似乎 gdbnasm https://github.com/pyparsing/pyparsing/blob/d27fd7627f3ed60b3b7a9e9f5e790d0e49107359/pyparsing_archive.py#L599-L1249 不太好。 nasm 生成一个名为 «function».label 的本地符号,这似乎让 gdb 感到困惑,因为它无法跟踪它所在的函数。

这是一种提供次优调试体验的场景:

section .text

global _start

_start:
  call foo
  ud2

foo:
  push rbp
  mov rbp,rsp
  call bar
.end:
  pop rbp
  ret

bar:
  ret

编译调试:

$ nasm -f elf64 -g -F DWARF example.asm -o example.o
$ ld example.o -o example
$ gdb ./example
Reading symbols from ./example...done.
(gdb) b foo
Breakpoint 1 at 0x400087: file example.asm,line 10.
(gdb) run
Starting program: /home/mvanotti/orga2/gdb/example 

Breakpoint 1,foo () at example.asm:10
10        push rbp
(gdb) ni
11        mov rbp,rsp
(gdb) ni
12        call bar
(gdb) ni

Program received signal SIGILL,Illegal instruction.
_start () at example.asm:7
7         ud2

如您所见,即使从 nexti 函数调用返回后,bar 仍继续执行。我相信这是因为 foo 中的下一条指令属于 foo.end 符号,导致 gdb 无法将其识别为函数的返回点。在 asm 文件中的 .end 标签之前添加任何其他指令可解决此问题。

同样,当它进入一个本地标签时,回溯会变得一团糟:

(gdb) 
foo.end () at example.asm:14
14        pop rbp
(gdb) bt
#0  foo.end () at example.asm:14
#1  0x0000000000000000 in ?? ()
(gdb) 

这也会影响 yasmlldb

对此没有明确的解决方法。我在 nasm 中找不到不发出 function.label 符号的选项,也找不到删除它们的简单方法。例如,strip 允许您指定 --wildcard 选项,但正则表达式语法太基本,无法匹配 .+\.* 之类的内容。我得到的最接近的是 strip --wildcard -N "*.*",但它也匹配 .something

gas 中,这是通过创建 .Llocal_label$ 形式的标签来解决的,该标签会被 ld 自动丢弃。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)