【问题标题】:How to make local labels in GNU GAS ELF output that GDB can break on but not count as functions?如何在 GDB 可以中断但不能算作函数的 GNU GAS ELF 输出中制作本地标签?
【发布时间】:2019-08-09 03:24:38
【问题描述】:

当使用 GNU GAS 手动编写程序集时,我想在一个函数中设置一个标签:

  • GDB 不会将该标签视为函数名
  • 我可以使用b mylabel 打破标签

nasm 的类似问题已在 Break at local label using GDB for NASM assembly 提出,但我想在这里更准确地说,我需要 GNU GAS 和 ELF 输出。

例如如果我定义了一个普通标签mylabel,如下所示:

main.S

.text
.global _start
_start:
    /* exit */
    mov $60, %rax
mylabel:
    mov $0, %rdi
    syscall

这并不让我满意,因为当 GDB 到达 mov $0, %rdi 时,btmylabel 显示为函数名称,而我希望它改为 _start。特别是,这可能会破坏回溯,因为 GDB 找不到堆栈帧:How gdb reconstructs stacktrace for C++?

但是,如果我将 mylabel 替换为 .Lmylabel,如下所述:Local labels in GNU assembler; gdb printing backtrace as though labels are functions_start 是所需的函数名称,但 b .Lmylabel 失败。 nm 也根本不显示符号。

ELF / DWARF 格式是否支持任何可以使用的东西,有没有办法通过 GNU GAS 来公开它?

在 Ubuntu 18.10、GDB 8.2、GNU GAS 2.31.1 中测试。

【问题讨论】:

    标签: gdb elf gnu-assembler dwarf


    【解决方案1】:

    我不确定这是否符合您的需求,但您可以这样做(对于非 PIE 二进制文件,请使用 -no-pie 链接):

    .text
    .global _start
    _start:
        /* exit */
        mov $60, %rax
    .Lmylabel:
        mov $0, %rdi
        syscall
        .section .rodata
    mylabel:
        .long .Lmylabel
    

    然后,您可以使用break *mylabel 设置断点(注意*):

    (gdb) break *mylabel
    Breakpoint 2 at 0x401007: file t.S, line 7.
    
    

    由于mylabel 或多或少是一个函数指针,GDB 对此一无所知,将忽略它:

    Breakpoint 1, _start () at t.S:5
    5       mov $60, %rax
    (gdb) si
    7       mov $0, %rdi
    

    使用链接器脚本,应该可以将mylabel 符号放入未加载的部分,以减少运行时开销。

    【讨论】:

    • 嗨,弗洛里安,我会记住这个提示,但它太老套了,我可能会让我的堆栈跟踪爆炸:-)(我的目标只是调试的用户友好性)。
    猜你喜欢
    • 2011-02-28
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    相关资源
    最近更新 更多