3
votes

I am trying to run an LLVM pass, but I get segmentation fault. Below is the code for my LLVM pass.

The compiler runs and produces the output. runOnBasicBlock works, but afterwards we get this error:

Segmentation fault (core dumped)

When I remove RegisterStandardPasses and loadPass (last lines), the code works fine. Any idea what causes this? Thanks

We load the compiler pass using the following line.

opt -load ./plugin_build/NvmInstrumenter.so -NvmInstrumenter -stats < simple.bc

We use LLVM and Clang version 5.0.0 both downloaded and built at the same time.

The code from the compiler pass:

#include "llvm/Pass.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/PassRegistry.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
// For output
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
  struct NvmInstrumenter : public BasicBlockPass {
    static char ID;
    NvmInstrumenter() : BasicBlockPass(ID) {}
    virtual bool runOnBasicBlock(BasicBlock &BB) {
      BasicBlock::iterator i;
      errs() << "Basic Block\n";
      for( i=BB.begin(); i!=BB.end(); i++ ) {
    errs() << "  " << i->getOpcodeName() << "\n";
      }
      return false;
    }
  };
}

// Pass info
char NvmInstrumenter::ID = 0; // LLVM ignores the actual value
static RegisterPass<NvmInstrumenter> X("NvmInstrumenter", "Example pass", false, false);

static void loadPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
  PM.add(new NvmInstrumenter());
}

static RegisterStandardPasses clangtoolLoader_Ox(PassManagerBuilder::EP_OptimizerLast, loadPass);
static RegisterStandardPasses clangtoolLoader_O0(PassManagerBuilder::EP_EnabledOnOptLevel0, loadPass);

Here is the backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ff4900 in ?? ()
(gdb) bt
#0  0x00007ffff7ff4900 in ?? ()
#1  0x00007ffff58fb4ab in llvm::object_deleter<llvm::SmallVector<std::pair<llvm::PassManagerBuilder::ExtensionPointTy, std::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)> >, 8u> >::call(void*) () from /usr/lib/llvm-5.0/bin/../lib/libLLVM-5.0.so.1
#2  0x00007ffff4cef87d in llvm::ManagedStaticBase::destroy() const () from /usr/lib/llvm-5.0/bin/../lib/libLLVM-5.0.so.1  
#3  0x00007ffff4cefa15 in llvm::llvm_shutdown() () from /usr/lib/llvm-5.0/bin/../lib/libLLVM-5.0.so.1
#4  0x00005555555f0ddf in main ()
1
It works ok here. Can you use gdb for more info? Also, if you are not planning to run your pass from clang, you can omit that pass registration, especially if it's on level O0. - compor
gdb doesn't give us any useful answer. It just says Segmentation fault. We intend to run it from clang. - user2776945
You can use the command bt in gdb to obtain a backtrace (call stack) after it hit the segmentation fault - PaulR
I can reproduce this issue. Someone else reported the bug here bugs.llvm.org/show_bug.cgi?id=34573 there doesn't seem to be any solution at this point. Did you have any luck fixing this? - greenbender

1 Answers

1
votes

You're not alone with this error (https://bugs.llvm.org/show_bug.cgi?id=34573), LLVM seems to crash at the end of the program when RegisterStandardPasses is used since LLVM 5.

According to this answer: https://github.com/sampsyo/llvm-pass-skeleton/issues/7#issuecomment-401834287 a solution is to add -Wl,-znodelete to the compiler flags when you link your program. It worked for me.