-
Notifications
You must be signed in to change notification settings - Fork 15.6k
Description
| Bugzilla Link | 5201 |
| Resolution | FIXED |
| Resolved on | Nov 17, 2015 11:45 |
| Version | trunk |
| OS | Linux |
| Attachments | Add asserts, against trunk r84189, Add a test for the bug, against trunk r84531 |
| Reporter | LLVM Bugzilla Contributor |
| CC | @comex,@echristo,@edwintorok,@rnk |
Extended Description
On x86-64 systems, we're observing segfaults that we believe to have tracked down to a codegen problem in the JIT:
Disassembling the buggy function in gdb gives us this:
... asm ...
0x00002aaab33482b1 <_23_u_23___init__45+673>: incq (%r14)
0x00002aaab33482b4 <_23_u_23___init__45+676>: mov 0x18(%rsp),%rbx
0x00002aaab33482b9 <_23_u_23___init__45+681>: mov %r14,(%rbx)
0x00002aaab33482bc <_23_u_23___init__45+684>: mov $0x2dd8b48,%rbx
0x00002aaab33482c6 <_23_u_23___init__45+694>: mov 0x18(%rbx),%rsi
0x00002aaab33482ca <_23_u_23___init__45+698>: mov %r14,%rdi
0x00002aaab33482cd <_23_u_23___init__45+701>: callq 0x2aaaa5c810b0
0x00002aaab33482d2 <_23_u_23___init__45+706>: mov (%r14),%rbx
0x00002aaab33482d5 <_23_u_23___init__45+709>: dec %rbx
... asm ...
(gdb) x 0x2aaaa5c810b0
0x2aaaa5c810b0: Cannot access memory at address 0x2aaaa5c810b0
That callq 0x2aaaa5c810b0 instruction is the problem: it's calling to invalid memory. Looking at the other callq instructions in this function, gdb can't
access any of them. callq addresses in other functions can be accessed by gdb.
What's happening is that now that the JIT memory manager can allocate multiple code slabs, there's no protection against having stub slabs and code slabs more than 32 bits distant from each other. If the memory manager allocates a new code slab far away from the stub, the offset will be truncated to 32 bits, which means that Bad Things Happen.
I'm working on a reduced test case, but in the meantime, I think the attached patch should be applied to trunk so that the offset is no longer silently truncated.
Applying this patch and passing -debug-only=jit will show this output when running part of Unladen Swallow's test suite:
[...tests...]
test_importhooks
test_enumerate
test_getopt
test_codecencodings_cn
JIT: Allocating another slab of memory for function.
python: /usr/local/google/collinwinter/us/trunk/Util/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:652:
void*::JITEmitter::getPointerToGlobal(llvm::GlobalValue*, void*, bool): Assertion `(Offset & 0xFFFFFFFF) == Offset && "Offset
too big for 32 bits"' failed.
Stack dump:
0. Running pass 'X86 Machine Code Emitter' on function '@"#u#readline241"
Without this, you'd see a segfault instead.