0
我想編譯一個函數(「fun」)到LLVM IR並使用ParseIR函數創建一個模塊。該程序在ParseIR調用中發生段錯誤。我使用的是LLVM 3.5,代碼如下。LLVM ParseIR Segfault
#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_os_ostream.h"
using std::cout;
using std::endl;
using std::ostringstream;
using std::string;
using llvm::getGlobalContext;
using llvm::LLVMContext;
using llvm::MemoryBuffer;
using llvm::Module;
using llvm::ParseIR;
using llvm::SMDiagnostic;
using llvm::StringRef;
int main() {
string fun = "int fun(int x) {return x;}\n";
string cmd = "echo '" + fun + "' |"
+ " clang++ -cc1 -xc++ -O0 -std=c++1y -fno-use-cxa-atexit"
+ " -I/usr/local/lib/clang/3.5.0/include/"
+ " -I/usr/include/c++/4.9/"
+ " -I/usr/include/x86_64-linux-gnu/c++/4.9/bits/"
+ " -I/usr/include/x86_64-linux-gnu -I/usr/include/"
+ " -I/usr/include/x86_64-linux-gnu/c++/4.9/"
+ " -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include/"
+ " -I/usr/include/c++/4.9/backward/"
+ " -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed/"
+ " -stdlib=libstdc++ -S -emit-llvm"
+ " -o /dev/stdout 2> /dev/stdout";
FILE *file = popen(cmd.c_str(), "r");
ostringstream llvm;
char line[1024];
while (fgets(line, 1024, file))
llvm << line;
pclose(file);
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMContext &ctx = getGlobalContext();
SMDiagnostic *err;
StringRef ref = StringRef(llvm.str().c_str());
MemoryBuffer *buff = MemoryBuffer::getMemBuffer(ref);
cout << "***** C++ *****\n" << fun << "\n"
<< "***** LLVM *****\n" << llvm.str() << endl;
//segfault
Module *mod = ParseIR(buff, *err, ctx);
return 0;
}
我編譯和使用下面的命令運行上面的代碼:
g++ -std=c++14 fun.cpp -o fun `llvm-config --cxxflags --ldflags --libs --system-libs`
./fun
***** C++ *****
int fun(int x) {return x;}
***** LLVM *****
; ModuleID = '-'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: nounwind
define i32 @_Z3funi(i32 %x) #0 {
%1 = alloca i32, align 4
store i32 %x, i32* %1, align 4
%2 = load i32* %1, align 4
ret i32 %2
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5.1 (branches/release_35 225591)"}
Segmentation fault (core dumped)
這似乎並不成爲一個問題,但我也想警惕StringRef的'(llvm.str()。c_str())',因爲StringRef沒有自己的內容。 – zneak
我編寫了一個答案,並用在我的程序中正常工作的方式替換了您的StringRef和MemoryBuffer初始化。你不必自己處理'StringRef's。只需將'std :: string'傳遞給'StringRef'參數即可。 –
修正了這個問題,現在'ParseIR'正常工作,謝謝!然而,我遇到了下面的代碼,我嘗試添加下面的代碼: 'for(Module :: iterator i = mod-> begin(); i!= mod-> end(); + + i){...}' – agg212