【问题标题】:How can I make gdb "grok" functions written in in-line assembly?如何使 gdb “grok”函数用内联汇编编写?
【发布时间】:2016-12-16 21:10:03
【问题描述】:

考虑以下简单的 GCC 程序:

#include <stdio.h>

int calledtest(int a)
{
    return(a + 5);
}

asm(
    ".pushsection .text;"
    ".type calltest, @function;"
    "calltest:"
    "  call calledtest;"
    "  ret;"
    ".size calltest, .-calltest;"
    ".popsection;"
);

int calltest(int);

int main(int argc, char **argv)
{
    printf("%i\n", calltest(2));
    return(0);
}

这个程序按预期工作,但我的问题是,当在 gdb 中运行它时,gdb 不知道如何“进入”calltest 函数。在printf 行上运行step 命令只需直接进入printf,完全跳过calltest 调用。请注意,在我当前的用例中,进入calltest 本身对我来说并不是一个真正的问题,但更困扰我的是gdb 甚至跳过了对calledtest 的整个调用。我当然可以通过步进指令进入calltestcalledtest,但这可能非常乏味,尤其是当calltest 在一行中调用复杂表达式和/或其他函数调用时。

如果我将calltest 函数放入我使用 GAS 编译的自己的单独程序集文件中,我可以简单地将 -g 标志传递给 GAS,gdb 将完全按预期工作,但我不知道任何使 GCC 与内联汇编类似的方法,我确实需要内联汇编,因为我使用 CPP 宏生成我的这些小存根作为更大库的一部分。

在我看来这是可以修复的不知何故,因为calltest 似乎与 gdb 肯定没有问题的标准 PLT 存根非常相似,但我不知道如何为这些生成调试信息。

所以我的问题是双重的:首先,gdb 真正在寻找什么样的信息来“理解”这些函数,其次,我如何生成它?

【问题讨论】:

  • 也许您应该为calltest 定义一个普通的C 函数,并将asm() 作为函数体。
  • @Barmar:通常我可能会同意,但实际上我使用这些存根有点不同。具体来说,我跳转到目标函数而不是调用它(类似于 PLT 存根,或优化的尾调用)。
  • 我怀疑问题是asm()没有将calltest放在调试信息中,这是调试器使用的。
  • @Barmar:确实。问题是如何手动完成。

标签: c gcc gdb


【解决方案1】:

.loc.cfi_* 指令似乎可以做到这一点。为了让.loc 工作,我必须将每条指令放在单独的行中:

asm(
    ".pushsection .text\n"
    ".type calltest, @function\n"
    "calltest:\n"
    ".loc 1 14 0\n"
    ".cfi_startproc\n"
    "  call calledtest\n"
    "  ret\n"
    ".cfi_endproc\n"
    ".size calltest, .-calltest\n"
    ".popsection\n"
);

【讨论】:

  • 实际上,仅.loc 指令似乎就足够了。我已经尝试过 CFI 的东西并且没有任何区别。但是,令人烦恼的是,当使用某些优化标志(在我的情况下为-Ofast -march=native)进行编译时,GCC 似乎会将程序集块移动到它分配文件名之前,这使得.loc 指令失败,所以我'我不知道如何使它健壮。但它确实回答了这个问题,所以谢谢!
  • @Dolda2000 实际情况是.cfi 指令是必需的,GCC 永远不会重新安排内联汇编,而.loc 指令是完全可选的。你似乎得出了一大堆错误的结论。
  • @EmployedRussian:我不这么认为。众所周知,当优化开启时,GCC 可以对程序的顶层部分进行重新排序,因此内联汇编很可能相对于程序的其他部分进行重新排序。在这种情况下,检查来自 GCC 的中间程序集输出确认确实发生了这种情况。至于哪些指令是“必需的”,我只能给出经验观察,即当包含.loc 指令时,gdb 按预期工作,但在仅包含.cfi 指令时不能。不确定如何从中得出“错误结论”。
猜你喜欢
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 2018-09-25
  • 2014-07-24
相关资源
最近更新 更多