[LLVMdev] Crash in JIT

David Mirabito david.mirabito at gmail.com
Tue Apr 24 23:48:49 PDT 2012


Hello,

[Using LLVM r155315, according to `svn log | head`]

I am experimenting with programatically building and jitting functions in a module, and I seem to be coming across a crash in some generated code. Using the llvm-c interface I build up the module which dumps like this:
; ModuleID = 'MyModule'
target datalayout = "i686-apple-darwin11"
target triple = "i686-apple-darwin11"

define i32 @functionName(i32 %m, i32 %x, i32 %b) {
entry:
  %mx = mul i32 %m, %x
  %y = add i32 %mx, %b
  ret i32 %y
}

Which looks OK to me. Note I'm not 100% sure (actually, I suspect is wrong) about the 'target datalayout' but with or without that line makes no difference to my results.

When I attempt to run the JIT (interpreter works fine) I get a EXC_BAD_ACCESS with the following backtrace:
* thread #1: tid = 0x2007, 0x0000000102e00042, stop reason = EXC_BAD_ACCESS (code=1, address=0x60c93a2c)
    frame #0: 0x0000000102e00042
    frame #1: 0x00000001015c01fb LLVMPlayGround`llvm::JIT::runFunction(llvm::Function*, std::vector<llvm::GenericValue, std::allocator<llvm::GenericValue> > const&) + 4747 at JIT.cpp:547
    frame #2: 0x00000001015a0db2 LLVMPlayGround`LLVMRunFunction + 322 at ExecutionEngineBindings.cpp:195
    frame #3: 0x0000000101096125 LLVMPlayGround`main + 741 at main.c:91
    frame #4: 0x0000000101095e34 LLVMPlayGround`start + 52

Which looks to be in some non-c code. At least XCode cannot find any corresponding source:
0x102e00042:  movl   $10, (%rsp) <-- DIE
0x102e00049:  movl   $5, 4(%rsp)
0x102e00051:  movl   $1, 8(%rsp)
0x102e00059:  movl   %eax, 24(%rsp)
0x102e0005d:  movl   %ecx, 20(%rsp)
It looks like marshalling the 3 arguments to my function.

Looking at rsp it looks like the top 32bits have been truncated, compared to other pointers floating around the system:
  rbp = 0x00007fff60c94070
  rsp = 0x0000000060c93a2c  
  r8 = 0x00007fff60c93800
  r9 = 0x00007fff60c93808

If I use the debugger to poke 0x00007fff into the top half of rsp, stepping through works, and after one jump I get to my function; I see the mul and add instruction. Continuing to step, I need one more fixup of rsp (perhaps corresponding to two jitted functions: mine, and the auto-built nullary stub?) before returning to my main function.

Is there anything obvious I've missed? Sorry for the long mail but I figure if I put all my data, then where I went wrong would be more obvious to someone who knows what they're doing :)

Thanks, and please let me know if there's anything extra I can add.
-DavidM

PS: below is my complete source.


#include <stdio.h>
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS

#include "llvm-c/Core.h"
#include "llvm-c/ExecutionEngine.h"

int main(int argc, const char * argv[])
{

    LLVMContextRef llvm;
    llvm = LLVMContextCreate();
    
    LLVMModuleRef module;
    module = LLVMModuleCreateWithNameInContext("MyModule", llvm);
    //LLVMSetDataLayout(module, "i686-apple-darwin11"); <-- is needed? What is correct?
    LLVMSetTarget(module, "i686-apple-darwin11");

    
    LLVMTypeRef int32 = LLVMInt32TypeInContext(llvm);
    
    LLVMTypeRef funcType;
    LLVMTypeRef threeInts[] = {int32, int32, int32};
    funcType = LLVMFunctionType(int32, threeInts, 3, 0);
    
    LLVMValueRef func;
    func = LLVMAddFunction(module, "functionName", funcType);

    LLVMValueRef mParam = LLVMGetParam(func, 0);
    LLVMSetValueName(mParam, "m");
    
    LLVMValueRef xParam = LLVMGetParam(func, 1);
    LLVMSetValueName(xParam, "x");
    
    LLVMValueRef bParam = LLVMGetParam(func, 2);
    LLVMSetValueName(bParam, "b");
    
    LLVMBasicBlockRef entryBB;
    entryBB = LLVMAppendBasicBlockInContext(llvm, func, "entry");

    LLVMBuilderRef builder;
    builder = LLVMCreateBuilderInContext(llvm);
    
    LLVMPositionBuilderAtEnd(builder, entryBB);
    
    LLVMValueRef mx;
    mx = LLVMBuildMul(builder, mParam, xParam, "mx");
    
    LLVMValueRef y;
    y = LLVMBuildAdd(builder, mx, bParam, "y");
    
    LLVMValueRef retInst;
    retInst = LLVMBuildRet(builder, y);
    (void) retInst;
    
    
    LLVMDisposeBuilder(builder);
    

    LLVMLinkInJIT();
    LLVMLinkInInterpreter();
    LLVMInitializeNativeTarget();
    
    LLVMDumpModule(module);
    
    /* Now run it! */
    
    LLVMExecutionEngineRef jit = NULL;
    char *err;
//    LLVMBool result = LLVMCreateExecutionEngineForModule(&jit, module, &err);
    LLVMBool result = LLVMCreateJITCompilerForModule(&jit, module, 0, &err);
    if (result) {
        printf("Fail: %s\n", err);
        return -1;
    }
    printf("JIT is %p\n", jit);
    
    LLVMGenericValueRef argM = LLVMCreateGenericValueOfInt(int32, 10, 0);
    LLVMGenericValueRef argX = LLVMCreateGenericValueOfInt(int32, 5, 0);
    LLVMGenericValueRef argB = LLVMCreateGenericValueOfInt(int32, 1, 0);    
    
    LLVMGenericValueRef args[] = {argM, argX, argB};
    LLVMGenericValueRef result2 = LLVMRunFunction(jit, func, 3, args);
    unsigned long long answer = LLVMGenericValueToInt(result2, 0);
    printf("And the answer is %d\n", (int)answer);
    
    LLVMDisposeModule(module);
    LLVMContextDispose(llvm);
    return 0;
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120425/bb08fbdf/attachment.html>


More information about the llvm-dev mailing list