[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