LLVM中设置DebugLoc后出现Subprogram不匹配错误求助
解决LLVM中
mismatched subprogram between llvm.dbg.value variable and !dbg attachment错误 咱们先直接拆解错误的核心原因:
mismatched subprogram between llvm.dbg.value variable and !dbg attachment
这条错误的本质是:你给llvm.dbg.value指令设置的!dbg(调试位置元数据)所属的子程序(Subprogram),和这条指令关联的局部变量所属的子程序完全不匹配。
看你贴的错误片段就能明白:
!42467是DILocalVariable(对应变量byte),它的作用域是!42461——也就是byteswap函数;- 但你给这条
llvm.dbg.value指令设置的!dbg !45649,它的作用域是!42421——也就是read_bin20hmm函数。
LLVM的调试信息规则明确要求:llvm.dbg.value关联的变量,必须和指令的调试位置属于同一个子程序,否则就会触发这个不匹配错误。
为什么你的代码会触发这个问题?
看你第二个Pass里设置DebugLoc的代码:
DebugLoc L = DebugLoc::get((unsigned)line, (unsigned)0, (*it)->getParent()->getParent()->getSubprogram());
你这里直接取了当前指令所在函数的Subprogram来创建DebugLoc,但如果这条指令是llvm.dbg.value,它关联的变量可能属于另一个函数(比如例子里的byteswap)——大概率是函数内联或者优化过程中,这条调试指令被移动到了其他函数里,但变量的归属还是原来的子程序。
而你说另一组指令没问题,是因为那组指令不是llvm.dbg.value这类调试指令,或者它们的变量和所在函数的Subprogram本来就是一致的,没有跨子程序的情况。
解决线索和代码修改建议
你需要对llvm.dbg.value这类调试指令做特殊处理,不要直接用当前函数的Subprogram,而是从指令关联的变量里获取正确的子程序:
修改第二个Pass的代码,增加对
llvm.dbg.value的判断逻辑:for (auto it = inst->dependent_insts.begin(), eit = inst->dependent_insts.end(); it != eit; it++) { if (MDNode* NN = (*it)->getMetadata("metadata_information")) { if ((*it)->getDebugLoc()) { std::string MDStr = cast<MDString>(NN->getOperand(0))->getString(); DebugLoc L; // 单独处理llvm.dbg.value指令 if (auto dbgValueInst = dyn_cast<DbgValueInst>(*it)) { // 从关联的局部变量中获取它所属的Subprogram auto localVar = cast<DILocalVariable>(dbgValueInst->getVariable()); auto subprogram = localVar->getScope()->getSubprogram(); L = DebugLoc::get((unsigned)line, (unsigned)0, subprogram); } else { // 普通指令沿用原来的逻辑,用当前函数的Subprogram L = DebugLoc::get((unsigned)line, (unsigned)0, (*it)->getParent()->getParent()->getSubprogram()); } line++; (*it)->setDebugLoc(L); errs() << "Metadata String: " << MDStr << "\n"; } } }额外检查点:
- 确认你的
dependent_insts集合里是否包含了其他调试相关指令(比如llvm.dbg.declare),这类指令也需要同样的处理逻辑; - 如果你的Pass涉及函数内联场景,要注意调试信息的继承和归属,避免随意修改跨子程序的调试位置。
- 确认你的
内容的提问来源于stack exchange,提问作者Ali94
相关产品推荐
相关产品推荐

