[LLVMdev] Crash in JIT

Kaylor, Andrew andrew.kaylor at intel.com
Wed Apr 25 10:36:56 PDT 2012


Hi David,

I'm not certain, but to me the "LLVMSetTarget(module, "i686-apple-darwin11");" line looks suspicious.  I'm not familiar with all the ins and outs of how target triples get handled, but it looks to me like that's requesting 32-bit code.

I think that if you omit that line completely then the target will be inferred from the execution environment.  My best guess as to what you would want if you do want to specify something explicit is "x86_64-apple-darwin11".

Someone who knows more about how the target works may correct me.

-Andy

From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of David Mirabito
Sent: Tuesday, April 24, 2012 11:49 PM
To: LLVM Developers Mailing List
Subject: [LLVMdev] Crash in JIT

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/d2bd6a0b/attachment.html>


More information about the llvm-dev mailing list