Hello,
I am new to llvm, I have written an llvm pass to insert a call to a specific function after each call Instruction.
This is the crash backtrace I got and I don’t understand the problem. (the code of the pass is included here if that might help)
Thank you in advance.
Stack dump:
0. Program arguments: opt-15 -load-pass-plugin lib/libInstrumentCall.so --passes=instr-call instrumentcall.ll
#0 0x00007fcdb0f35451 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xf04451)
[#1](https://github.com/llvm/llvm-project/pull/1) 0x00007fcdb0f3318e llvm::sys::RunSignalHandlers() (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xf0218e)
[#2](https://github.com/llvm/llvm-project/pull/2) 0x00007fcdb0f35976 (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xf04976)
[#3](https://github.com/llvm/llvm-project/pull/3) 0x00007fcdafb0a520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
[#4](https://github.com/llvm/llvm-project/pull/4) 0x00007fcdb10c8340 llvm::Value::getName() const (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0x1097340)
[#5](https://github.com/llvm/llvm-project/pull/5) 0x00007fcdad9ccb6c InstrumentCall::runOnModule(llvm::Module&) /home/ss/llvm-tutor/lib/InstrumentCall.cpp:74:82
[#6](https://github.com/llvm/llvm-project/pull/6) 0x00007fcdad9cce0e InstrumentCall::run(llvm::Module&, llvm::AnalysisManagerllvm::Module&) /home/ss/llvm-tutor/lib/InstrumentCall.cpp:97:30
[#7](https://github.com/llvm/llvm-project/pull/7) 0x00007fcdad9d4723 llvm::detail::PassModel<llvm::Module, InstrumentCall, llvm::PreservedAnalyses, llvm::AnalysisManagerllvm::Module>::run(llvm::Module&, llvm::AnalysisManagerllvm::Module&) /usr/include/llvm-15/llvm/IR/PassManagerInternal.h:89:3
[#8](https://github.com/llvm/llvm-project/pull/8) 0x00007fcdb10a61b9 llvm::PassManager<llvm::Module, llvm::AnalysisManagerllvm::Module>::run(llvm::Module&, llvm::AnalysisManagerllvm::Module&) (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0x10751b9)
[#9](https://github.com/llvm/llvm-project/pull/9) 0x0000562c08da8f37 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRefllvm::StringRef, llvm::ArrayRefllvm::PassPlugin, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool) (/usr/lib/llvm-15/bin/opt+0x22f37)
[#10](https://github.com/llvm/llvm-project/pull/10) 0x0000562c08dbac04 main (/usr/lib/llvm-15/bin/opt+0x34c04)
[#11](https://github.com/llvm/llvm-project/pull/11) 0x00007fcdafaf1d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
[#12](https://github.com/llvm/llvm-project/pull/12) 0x00007fcdafaf1e40 call_init ./csu/../csu/libc-start.c:128:20
[#13](https://github.com/llvm/llvm-project/pull/13) 0x00007fcdafaf1e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
[#14](https://github.com/llvm/llvm-project/pull/14) 0x0000562c08da1905 _start (/usr/lib/llvm-15/bin/opt+0x1b905)
Segmentation fault (core dumped)
This is the code for my llvm pass
#include "InstrumentCall.h"
#include "instrumentcall.c"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
using namespace llvm;
#define DEBUG_TYPE "instr-call"
//-----------------------------------------------------------------------------
// InstrumentCall implementation
//-----------------------------------------------------------------------------
bool InstrumentCall::runOnModule(Module &M) {
bool Instrumented = false;
auto &CTX = M.getContext();
// STEP 1: Inject the declaration of the function to call
// -------------------------------------------------------
llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(CTX), // return type
false // is varg function
);
// STEP 2: Chose where to inject the instrumentation
// -------------------------------------------------
auto InstFunc = M.getOrInsertFunction("instrumentcall", FT);
//auto InstFunc = Function::Create(FT, Function::ExternalLinkage, "instrumentcall", M);
for (auto &F : M) {
for(auto &B:F){
for(auto &I:B){
if(I.isTerminator()){
//errs() << "Instruction: "<< I << "\n";
if(I.getOpcodeName()=="ret")
errs() << "Opcode: "<< I.getOpcodeName() << "\n";
}
if(dyn_cast<CallInst>(&I)){
//errs() << "Instruction: "<< I << "\n";
//errs() << "Opcode: "<< I.getOpcodeName() << "\n";
StringRef called = dyn_cast<CallInst>(&I)->getCalledFunction()->getName();
errs() << "Called Function: "<< called << "\n";
// error in the IRBuilder constructor
if(!called.contains("instrumentcall"))
{
IRBuilder<> builder(&B);
builder.SetInsertPoint(I.getNextNode());
builder.CreateCall(InstFunc);
//Instruction *newInst = CallInst::Create(InstFunc, "");
//B.getInstList().insert(((Instruction*)&I)->getIterator(), newInst);
Instrumented = true;
}
}
}
}
}
return Instrumented;
}
PreservedAnalyses InstrumentCall::run(llvm::Module &M,
llvm::ModuleAnalysisManager &) {
bool Changed = runOnModule(M);
return (Changed ? llvm::PreservedAnalyses::none()
: llvm::PreservedAnalyses::all());
}
//-----------------------------------------------------------------------------
// New PM Registration
//-----------------------------------------------------------------------------
llvm::PassPluginLibraryInfo getInstrumentCallPluginInfo() {
return {LLVM_PLUGIN_API_VERSION, "instr-call", LLVM_VERSION_STRING,
[](PassBuilder &PB) {
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &MPM,
ArrayRef<PassBuilder::PipelineElement>) {
if (Name == "instr-call") {
MPM.addPass(InstrumentCall());
return true;
}
return false;
});
}};
}
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return getInstrumentCallPluginInfo();
}