后端Pass简介——JMCInstrumenter
JMCInstrumenter
JMCInstrumenter Pass 会在每个有调试信息的函数入口处插入一次对 __CheckForDebuggerJustMyCode 的调用,并自动生成默认实现和标志全局变量,以支持“Just My Code”调试。
背景:当我们在 IDE(如 Visual Studio)或调试器里调试本地 C/C++ 代码时,经常只关心“自己写的业务逻辑”——而不想单步进入运行时库、编译器插桩或 STL 之类的实现细节。微软在 MSVC 下把这个功能叫作 “Just My Code” (JMC);LLVM 也支持类似的体验。为此,需要在编译产出的机器码里“打标签”,告诉调试器「这些指令是用户代码/这些不是」,于是就有了 JMCInstrumenter 这个 Pass:它在每个函数入口插入一次钩子调用,runtime/debugger 就据此区分用户与非用户代码。
- Just My Code (JMC):调试特性,用来区分“用户自己写的代码”与运行时/库代码。
假设有个用户函数放在 src/foo.c:
; 原始函数
define i32 @foo(i32 %x) { … }
该Pass 会:
- 生成全局变量 __D1234ABC_foo@c,放在 .data.just.my.code 段,类型 i8 初始值 1。
2.(若无现成)创建一个空的 __JustMyCode_Default 函数,并:- ELF 下重命名为 __CheckForDebuggerJustMyCode、弱链接;
- MSVC 下用 /alternatename: 绑定。
- 在 @foo 的入口插入:
call void @__CheckForDebuggerJustMyCode(i8* bitcast (i8* @__D1234ABC_foo@c to i8*))
调试器在运行时就能识别“从这里开始是用户代码”。
该 Pass 支持 ELF 和 MSVC,但是默认是禁用的。
评论