现在LLVM 自定义的Pass中添加若干自定义指令,如何使用setDebugLoc等方式,使得在gdb调试时可以让引发异常的添加指令有正确的调试信息如行号等
时间: 2023-11-28 22:47:40 浏览: 76
在 LLVM 自定义 Pass 中添加自定义指令时,若想让这些指令在 GDB 调试时有正确的调试信息,可以考虑以下两个方面:
1. 添加调试信息
可以使用 LLVM 提供的 DebugInfoBuilder 和 DILocation 类来添加调试信息。例如,在自定义指令的生成函数中,可以使用以下代码添加调试信息:
```
DebugLoc loc = Builder.getCurrentDebugLocation();
DILocation *debugLoc = nullptr;
if (loc) {
debugLoc = loc.get();
} else {
debugLoc = DILocation::get(
M.getContext(), M.getDebugInfoFinder().compile_unit(), 0, 0);
}
Builder.SetCurrentDebugLocation(DebugLoc(debugLoc));
```
这段代码会从当前 Builder 中获取调试信息,如果没有则创建一个新的调试信息,并设置到 Builder 中。
2. 设置异常处理器
为了让 GDB 可以获取到引发异常的指令信息,可以在自定义指令的生成函数中添加异常处理器,并设置好异常处理器的调试信息。例如:
```
void MyCustomInstGenFunction::generate() {
// 添加调试信息
DebugLoc loc = Builder.getCurrentDebugLocation();
DILocation *debugLoc = nullptr;
if (loc) {
debugLoc = loc.get();
} else {
debugLoc = DILocation::get(
M.getContext(), M.getDebugInfoFinder().compile_unit(), 0, 0);
}
Builder.SetCurrentDebugLocation(DebugLoc(debugLoc));
// 设置异常处理器
Function *handler = /* 创建异常处理函数 */;
BasicBlock *resumeBlock = /* 创建 resumeBlock */;
auto *personalityFn = /* 获取当前函数的 personality function */;
auto *ehSelectorFn = /* 获取当前函数的 EH selector function */;
auto *catchSwitch = createInvokeAndSwitch(/* 创建 invoke and switch */);
catchSwitch->setDebugLoc(DebugLoc(debugLoc));
/* 添加 catch handler */
}
```
在创建 invoke and switch 时,需要设置 catchSwitch 的调试信息,并在添加 catch handler 时也要设置调试信息。
通过以上两个方面的设置,可以使得自定义指令在 GDB 调试时有正确的调试信息。
阅读全文