2016-03-20 5 views
2

Ben LLVM-C kullanarak basit bir program var: As isLLVMModule ve LLVMExecutionEngine doğru şekilde nasıl yok edilir?

#define __STDC_LIMIT_MACROS 
#define __STDC_CONSTANT_MACROS 

#include <llvm-c/Core.h> 
#include <llvm-c/ExecutionEngine.h> 
#include <llvm-c/Target.h> 
#include <llvm-c/Analysis.h> 
#include <llvm-c/BitWriter.h> 
#include <llvm-c/Linker.h> 

#include <stdlib.h> 
#include <stdio.h> 

int main() { 
    LLVMInitializeNativeTarget(); 
    LLVMInitializeNativeAsmPrinter(); 
    LLVMInitializeNativeAsmParser(); 

    LLVMContextRef ctx = LLVMGetGlobalContext(); 
    LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("mymodule", ctx); 
    LLVMTypeRef functype = LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0); 
    LLVMValueRef func = LLVMAddFunction(mod, "constfunc", functype); 

    LLVMBasicBlockRef entry = LLVMAppendBasicBlock(func, "entry"); 
    LLVMBuilderRef builder = LLVMCreateBuilder(); 
    LLVMPositionBuilderAtEnd(builder, entry); 
    LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 2, 0)); 
    LLVMDisposeBuilder(builder); 

    char* error = NULL; 
    LLVMVerifyModule(mod, LLVMAbortProcessAction, &error); 
    LLVMDisposeMessage(error); 
    error = NULL; 
    LLVMExecutionEngineRef engine; 
    if (LLVMCreateMCJITCompilerForModule (&engine, mod, NULL, 0, &error) != 0) { 
     fprintf(stderr, "failed to create execution engine\n"); 
     exit(EXIT_FAILURE); 
    } 

    int (*func_p)(void) = (int(*)(void)) LLVMGetFunctionAddress(engine, "constfunc"); 
    printf("%d\n", func_p()); 

    LLVMDisposeExecutionEngine(engine); 
    LLVMDisposeModule(mod); 

    return 0; 
} 

, bu LLVMDisposeModule içinde çalışma sırasında parçalama arızası:

(gdb) run 
Starting program: /home/col/llvmtest 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 
2 

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff668fbcc in llvm::SmallPtrSetImplBase::erase_imp(void const*)() from /usr/local/lib/libLLVM-3.7.1.so 
(gdb) bt 
#0 0x00007ffff668fbcc in llvm::SmallPtrSetImplBase::erase_imp(void const*)() from /usr/local/lib/libLLVM-3.7.1.so 
#1 0x00007ffff5d60f00 in llvm::Module::~Module()() from /usr/local/lib/libLLVM-3.7.1.so 
#2 0x00007ffff5c62b5e in LLVMDisposeModule() from /usr/local/lib/libLLVM-3.7.1.so 
#3 0x00000000004010cd in main() at llvmtest.c:44 

Ancak, ben LLVMDisposeExecutionEngine veya LLVMDisposeModule çağrısı ya dışarı yorum yaparsanız bunu artık segfaults.

C API kullanarak LLVM modülünü ve yürütme altyapısını imha etmenin doğru yolu nedir? Ben listelenen koduyla iki sorun,

birinci sorunu ve sorgunuzu görüyorum

+0

: https://lists.freedesktop.org/archives/mesa-dev/2014-May/059352.html LLVMDisposeExecutionEngine da bu yüzden sadece tercihen bunlardan birini çağırmak, modül elden varsa motor. –

cevap

1

, bunu, yürütme motorunun modül listesine modül temin aşağıda ExecutionEngineBindings aynı için kesim kodudur eklendi LLVMCreateMCJITCompilerForModule denilen olduğunu .Cpp: Eğer LLVMDisposeExecutionEngine aradığında 196

std::string Error; 
EngineBuilder builder(std::move(Mod)); 
builder.setEngineKind(EngineKind::JIT) 
      .setErrorStr(&Error) 
      .setOptLevel((CodeGenOpt::Level)options.OptLevel) 
      .setCodeModel(unwrap(options.CodeModel)) 
      .setTargetOptions(targetOptions); 
    if (options.MCJMM) 
    builder.setMCJITMemoryManager(
     std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM))); 
    if (ExecutionEngine *JIT = builder.create()) { 
    *OutJIT = wrap(JIT); 

nedenle motorun listesinde tüm modülleri, silinmiş, bu yüzden doğru yolu yürütme motorunu atmadan önce listeden modülü/sn kaldırmak gerekir olduğunu.) (LLVMInitializeNativeTarget önce olmalıdır LLVMLinkInMCJIT() hiçbir çağrı yoktur,

LLVMRemoveModule(engine, mod, &mod, &error); 
LLVMDisposeExecutionEngine(engine); 

ve ikinci tam zamanında bağlantılı edilmemiştir olduğu; (258 kod aynı dosya ExecutionEngineBindings.cpp olan) Burada gördüklerimize göre

LLVMLinkInMCJIT(); 
LLVMInitializeNativeTarget();