【问题标题】:Is there a debugger for LLVM IR?LLVM IR 有调试器吗?
【发布时间】:2015-08-13 09:33:16
【问题描述】:

我想逐步了解我生成的一些 LLVM IR 代码。就 llc 和 lli 而言,代码在语法上和类型有效,但结果不是我所期望的。

这些块足够大,以至于我无法简单地读出错误,而且我很难生成具有相同错误的较小示例。

我想我可以使用调试器之类的东西,但对于 LLVM IR。换句话说,我希望能够单步执行 llvm 代码,检查“无限”寄存器(给定 LLVM IR 文件中的名称)和内存位置,设置断点,直到找到我的代码出错的地方。

我查看了llilldb,但似乎都不是我要寻找的工具。 lli 会运行我的代码,但不会让我一步一步走。 lldb 似乎假设代码是由 C 前端生成的。

lldblli 我错了吗?有谁知道一个工具可以完成我想要的 50% 的工作?

【问题讨论】:

  • 作为一个疯狂的猜测 - 您可以调试 lli 并查看它如何解释每条指令。不过,您必须进行一些黑客攻击才能设置断点。

标签: llvm llvm-ir


【解决方案1】:

我不知道这样的事情(我怀疑它不存在)。虽然我很乐意分享关于 llvm 生成的代码调试的观点。

  1. 调试生成的代码本身(在 gdb 中逐步调试)。
  2. 利用debugtrap 内在函数(它只生成int3 或架构上的任何等效项)。你可以用这个东西做出断言,看看它们中的哪一个失败了。
  3. 给你的指令命名(所以它们不是%0%1,而是有意义的%names)——它们在llc输出中显示为cmets。
  4. 为您的函数构建 CFG(控制流图):opt --dot-cfg 1.ll; dot cfg.funcname.dot -Tpng > 1.png
  5. 不要忘记禁用 llvm 优化(您可以使用后端 -O3 优化级别,但 IR 转换通道会使调试变得更加困难)。

所以我建议的工作流程如下。构建 CFG (4.) 和组件(通过 llc)。中断 gdb 中生成的代码并单步执行它(或让它陷入您的一个断言)。将您在 gdb 中停止的点关联到 llc 输出,阅读评论,关联到 CFG。格罗克。

您还可以从生成的代码中构建 CFG 表示。在我所知道的工具中,IDA Pro(构建 CFG 的一种非常昂贵的方式)和 Saga 提供了这样的功能。

P.S.:这最初是一条评论,但它变得太长了。

【讨论】:

    【解决方案2】:

    曾经有一个 LLVM 通行证 -debug-ir 可以做到这一点。见this答案。

    已经有attempts 来恢复它,包括patch

    我需要一个这样的实用程序来调试我正在生成的一些代码。所以我将上面的补丁改编成一个独立的工具,它可以将行号信息附加到输入 LLVM-IR 文件中,并生成一个输出 LLVM-IR,其调试信息是指输入文件。 https://github.com/vaivaswatha/debugir

    【讨论】:

    • 我使用了你的工具,它给了我一个错误:Undefined command: "-jit-kind". Try "help".
    • @ar2015 您尝试的 gdb 命令应该以 set args 开头。这是我的一个错误,我现在已经解决了。感谢您提请我注意。
    • 非常感谢。现在很好。该库缺少的是如何使用在输出代码中添加的符号的解释。我什至不知道如何使用debugir 输出在gdb 中打印变量%12
    • 我在这里提出了一个问题:stackoverflow.com/q/67240807/4623526
    【解决方案3】:

    我正在寻找同样的东西,我发现了这个:Debugging JIT-ed Code With GDB

    1) 用 clang 编译并发出字节码

    clang++ -emit-llvm -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -DDEBUG  -O0  -m64 -fomit-frame-pointer -c a.cpp -g -fno-use-cxa-atexit
    clang++ -emit-llvm -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -DDEBUG  -O0  -m64 -fomit-frame-pointer -c b.cpp -g -fno-use-cxa-atexit
    

    2) 与 llvm-link 链接

    llvm-link -o all.bc a.bc b.bc
    

    3) 使用 jit 使用 gdb 和 lli 进行调试

    gdb --quiet --args lli -jit-kind=mcjit all.bc
    
    
    (gdb) b initCloneLookups
    Function "initCloneLookups" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (initCloneLookups) pending.
    
    (gdb) r
    Starting program: lli -jit-kind=mcjit all.bc
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    ......
    
    
    Breakpoint 1, initCloneLookups () at a.cpp:66
    66              clone_lookups = new BitBoard64[61];
    

    在设置断点处回答“y”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-11
      • 1970-01-01
      • 2017-04-09
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      相关资源
      最近更新 更多