4

我正在根据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
4

0 回答 0