我正在根据LLVM 网站上的教程编写玩具编译器,但现在在代码生成期间出现错误(我相信)。程序在llvm::TypeFinder::incorporateValue
方法中因段错误而崩溃,我无法弄清楚发生了什么。
这是崩溃发生时 LLDB 的输出。
* thread #1: tid = 0x2dfc, 0x0000000000a2a2d0 wtf`llvm::TypeFinder::incorporateValue(llvm::Value const*) + 16, stop reason = invalid address
frame #0: 0x0000000000a2a2d0 wtf`llvm::TypeFinder::incorporateValue(llvm::Value const*) + 16
wtf`llvm::TypeFinder::incorporateValue(llvm::Value const*) + 16:
-> 0xa2a2d0: movb 8(%r14), %al
0xa2a2d4: cmpb $17, %al
0xa2a2d6: jne 0xa2a332 ; llvm::TypeFinder::incorporateValue(llvm::Value const*) + 114
0xa2a2d8: movq %r14, (%rsp)
当我尝试转储函数的 IR 代码、在verifyFunction
其上运行或FunctionPassManager
尝试优化它时,就会发生这种情况。当 FPM 运行时,它会失败并显示
Stack dump:
0. Running pass 'Module Verifier' on function '@foo'
[1] 11485 segmentation fault (core dumped) bin/wtf examples/simple.wtf
这是产生错误的代码
Function *Codegen::Generate(FunctionAST *funcAst) {
NamedValues.clear();
Function *func = this->Generate(funcAst->GetPrototype());
if (func == 0)
return 0;
BasicBlock *block = BasicBlock::Create(getGlobalContext(), "entry", func);
Builder.SetInsertPoint(block);
// iterate and codegen all expressions in body
Value *retVal = this->Generate(funcAst->GetBody());
if (retVal) {
Builder.CreateRet(retVal);
verifyFunction(*func);
TheFPM->run(*func); // <----- crash happens here
return func;
}
func->eraseFromParent();
return 0;
};
我正在寻找崩溃的原因或只是某种缩小范围的方法,因为逐步使用 LLDB 对我没有多大帮助(可能是因为我不了解 LLVM 的内部结构)
这是 LLDB 失败时的回溯verifyFunction
:
frame #0: 0x0000000000a2a225 wtf`llvm::TypeFinder::incorporateType(llvm::Type*) + 53
frame #1: 0x0000000000a29e1b wtf`llvm::TypeFinder::run(llvm::Module const&, bool) + 91
frame #2: 0x000000000098d91b wtf`(anonymous namespace)::TypePrinting::incorporateTypes(llvm::Module const&) + 27
frame #3: 0x00000000009907f5 wtf`llvm::Value::print(llvm::raw_ostream&, llvm::AssemblyAnnotationWriter*) const + 2421
frame #4: 0x0000000000a316cf wtf`(anonymous namespace)::Verifier::CheckFailed(llvm::Twine const&, llvm::Value const*, llvm::Type*, llvm::Value const*) + 143
frame #5: 0x0000000000a30ca5 wtf`(anonymous namespace)::Verifier::visitFunction(llvm::Function&) + 421
frame #6: 0x0000000000a2fd84 wtf`(anonymous namespace)::Verifier::runOnFunction(llvm::Function&) + 132
frame #7: 0x0000000000a1d99e wtf`llvm::FPPassManager::runOnFunction(llvm::Function&) + 318
frame #8: 0x0000000000a1d243 wtf`llvm::FunctionPassManagerImpl::run(llvm::Function&) + 195
frame #9: 0x0000000000a1d11d wtf`llvm::FunctionPassManager::run(llvm::Function&) + 93
frame #10: 0x0000000000a2f98a wtf`llvm::verifyFunction(llvm::Function const&, llvm::VerifierFailureAction) + 538
frame #11: 0x00000000004cef02 wtf`Codegen::Generate(this=<unavailable>, funcAst=<unavailable>) + 226 at Codegen.cpp:325
frame #12: 0x00000000004da96b wtf`Driver::Go(std::string) [inlined] Driver::HandleDefinition(this=<unavailable>) + 27 at Driver.cpp:5
frame #13: 0x00000000004da950 wtf`Driver::Go(this=<unavailable>, file=<unavailable>) + 208 at Driver.cpp:61
frame #14: 0x00000000004db71c wtf`main(argc=<unavailable>, argv=<unavailable>) + 364 at main.cpp:30
frame #15: 0x00007ff648bb476d libc.so.6`__libc_start_main + 237
frame #16: 0x00000000004cb9bd wtf`_start + 41