GDB JIT接口最简单的例子

Ori*_*ent 9 c++ debugging jit gdb

我阅读了JIT接口章节并遇到了问题:如何为最简单的可能代码编写一个最简单的示例(最好是在C++中,至少在x86-64平台上)?说,我想调试以下代码(即code_.data()函数):

#include "eallocator.hpp"

#include <iostream>
#include <vector>

#include <cstdlib>

int main()
{
    std::vector< std::uint8_t, eallocator< std::uint8_t > > code_;
    code_.push_back(0b11011001u); code_.push_back(0b11101011u); // fldpi
    code_.push_back(0b11000011u);                               // ret

    double result_;
    __asm("call *%1"
            : "=&t"(result_)
            : "r"(code_.data())
            :
              );
    std::cout << result_ << std::endl;

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

使用界面我应该做什么(最低限度)?特别是,我希望能够提供一些伪代码(内存中的任意文本)作为"源"(具有相应的行信息),如果可能的话.

如何检测上面的代码(或类似的东西),同时保持简洁.

#include "eallocator.hpp"应该使用针对Windows的方法或针对Linux的方法.

Eli*_*sky 4

如果我理解正确的话,您想要做的就是动态地将一些可执行代码发送到内存中并设置 GDB 以便能够调试它,对吗?

这个任务很难用“最小”的例子来表达,因为 GDB 实际上希望在内存中找到整个 ELF 对象,而不仅仅是一堆代码。GDB 的注册接口需要 ELF 符号表来检查,以便找出发出的代码中存在哪些符号以及它们所在的位置。

无需付出不合理的努力即可做到这一点的最佳选择是查看 LLVM。文档中的使用 GDB调试JIT 代码部分描述了如何使用 MCJIT 执行此操作,底部有一个完整的示例 - 从一些简单的 C 代码开始,使用 LLVM MCJIT 将其 JIT 到内存并将 GDB 附加到它。此外,由于涉及 LLVM MCJIT 框架,您可以在那里获得完整的调试信息,直至 C 级别!

老实说,该文档部分已经有一段时间没有更新了,但它应该可以工作。如果没有,请告诉我 - 我会研究修复并更新它。

我希望这有帮助。