在 GDB 编译代码命令中,哪些语言结构的行为与它们在原始源代码中的表现完全相同? [英] In the GDB compile code command, what language constructs behave exactly as if they were present in the original source?

查看:17
本文介绍了在 GDB 编译代码命令中,哪些语言结构的行为与它们在原始源代码中的表现完全相同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GDB 最近引入了 compile 命令以在运行时注入代码,请参阅 this answer要求和一个最小的例子.

GDB recently introduced the compile command to inject code at runtime, see this answer for requirements and a minimal example.

但我注意到有一些东西好像我在当前位置的原始源代码中写的一样不起作用:

But I noticed that a few things do not work as if I had written them in the original source code at the current location:

  • 编译代码返回;不结束当前函数,只结束注入的代码.

  • compile code return; does not end the current function, only the injected code.

假设:代码在一个新的堆栈框架中运行,但其中局部变量仍然可见.

Hypothesis: code runs in a new stack frame, but one in which local variables are still visible.

寄存器修改失败,例如:

register modification fails, e.g.:

compile code asm volatile ("mov $0x123, %rbp");
p $rbp

输出:不是0x123.

假设:寄存器都在函数运行时保存和恢复.

Hypothesis: registers are all saved and restored on the function run.

除此之外,文档清楚地解释了注入的代码符号和类型在外面是不可见的.

Besides those, the documentation clearly explains that injected code symbols and types are not visible outside.

那么不起作用"的那些构造的一般理论/完整列表是什么?

So what is the general theory / full list of those constructs that "do not work"?

该功能的 GNU Cauldron 演示文稿包含功能使用和内部原理的概述:视频演示文稿

The GNU Cauldron presentation of the feature contains an overview of the feature usage and internals: video, presentation

该功能在 7.9.1 GDB 源代码的 compile/ 子目录中实现.

The feature is implemented on the compile/ subdirectory of the 7.9.1 GDB source code.

推荐答案

compile 命令的工作原理是发出一个新函数,用 gcc 编译它,然后从 gdb 调用该函数(一个劣函数调用"用 gdb 术语).

The compile command works by emitting a new function, compiling it with gcc, and then invoking the function from gdb (an "inferior function call" in gdb lingo).

代码生成器确实具有一些特殊功能,可以访问局部变量.特别是它将 DWARF 位置表达式转换为 C.对寄存器的引用被转换为对特殊 struct 中字段的引用.gdb 安排在执行低级调用时将相关寄存器复制到此结构的实例中.调用完成后,它会将寄存器复制回来——这允许写入局部变量.

The code generator does have some special features to make it possible to access local variables. In particular it translates DWARF location expressions to C. References to registers are translated into references to fields in a special struct. gdb arranges to copy the relevant registers into an instance of this struct when performing the inferior call. After the call has completed, it copies the registers back out -- this allows writes to local variables.

我认为,这个描述应该更清楚地说明什么可行,什么不可行.我希望 return 和其他控制流操作(breakcontinuegoto)不起作用.

This description should, I think, make it clearer what will work and what will not. I would expect return and other flow-of-control operations (break, continue, goto) not to work.

写入寄存器应该工作,但仅适用于某些位置表达式所需的寄存器.这也许可以解决;虽然我相信现在出于性能原因只传入必要的寄存器.

Writing to a register should work, but only for registers which are needed by some location expression. This could perhaps be fixed; though I believe right now only the necessary registers are passed in for performance reasons.

我不知道如果你的编译代码调用 longjmpthrow 会发生什么(好吧,当 C++ 被实现时).大概是疯了.

I don't know what would happen if your compiled code calls longjmp or throw (well, when C++ is implemented). Probably madness.

有一点值得了解的是,这段代码的设计是为了让未来的补丁可以添加编译断点条件,可能与 dyninst 之类的东西结合使用.

One thing worth knowing is that this code was designed so that a future patch could add compiled breakpoint conditions, perhaps in conjunction with something like dyninst.

这篇关于在 GDB 编译代码命令中,哪些语言结构的行为与它们在原始源代码中的表现完全相同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆