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

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

问题描述

GDB最近引入了 compile 命令在运行时注入代码,参见 this答案的要求和一个简单的例子。



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


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



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


  • 注册表修改失败,例如:

     编译代码asm volatile(mov $ 0x123, %RBP); 
    p $ rbp

    输出:不是 0x123 $ b

    假设:寄存器全部保存并在函数运行时恢复。




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

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


该功能的GNU Cauldron演示文稿包含功能使用情况和内部结构的概述:视频演示文稿



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

解方法

compile 命令通过发布一个新函数,使用gcc编译它,然后从gdb调用函数(一个劣等函数调用 gdb lingo)。



代码生成器有一些特殊的功能,可以访问局部变量。特别是它将DWARF位置表达式转换为C.对寄存器的引用被转换为对特殊 struct 中字段的引用。当执行次等呼叫时,gdb安排将相关寄存器复制到该结构的一个实例中。调用完成后,它将寄存器复制出来 - 这允许写入局部变量。



这个描述应该让我们更清楚地知道什么可以工作,什么不会。我期望 return 和其他控制流操作( break continue code>, goto )不起作用。

写入寄存器应该工作,但只适用于某些位置表达式所需的寄存器。这可能是固定的;虽然我相信现在只有必要的寄存器被传递出于性能原因。



我不知道如果你编译的代码调用会发生什么, longjmp throw (当C ++被实现时)。可能是疯狂的。



值得了解的一件事是,这个代码的设计使得未来的补丁可以添加编译的断点条件,也许与dyninst类似。 >

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
    

    Output: not 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"?

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

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

解决方案

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).

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.

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.

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

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天全站免登陆