Possible bug in latest version of clang on Mac OS X
Doug Simon
doug.simon at oracle.com
Fri Mar 14 11:11:38 UTC 2014
(sending again with attachment inline)
Thanks to more investigation by Tom, it appears as though clang is legally omitting the null pointer check according to one way of interpreting (recent?) C++ specification around the value and type of NULL.
For anyone interested, I took some of Tom’s example code and made it into a standalone program (below) showing the issue:
$ clang++ -O3 -o clang_omits_null_check clang_omits_null_check.cpp
$ ./clang_omits_null_check
1. argc = 1
2. argc = 1
Illegal instruction: 4
Switching to -O0 to prevents the crash:
$ clang++ -O0 -o clang_omits_null_check clang_omits_null_check.cpp
$ ./clang_omits_null_check
1. argc = 1
2. argc = 1
3. argc = 1
The only hints found on the web about this behavior so far are:
http://stackoverflow.com/questions/10153246/crashing-threads-with-intnull-1-problematic
http://blog.qt.digia.com/blog/2011/06/10/type-punning-and-strict-aliasing/
===== clang_omits_null_check.cpp ====
#include <stdio.h>
#include <stdint.h>
static char read1(char* handle, long offset) {
char* obj = handle == NULL ? NULL : *(char**) handle;
return *(char*)((intptr_t)obj + offset);
}
static char read2(char* handle, long offset) {
char* obj = handle == NULL ? NULL : *(char**) handle;
// Without the cast to intptr_t, this crashes since
// the compiler dereferences handle first and then
// adds offset to it.
return *(char*)( obj + offset);
}
int main(int argc, char** argv) {
int* argcAddr = &argc;
printf("1. argc = %d\n", argc);
printf("2. argc = %d\n", read1(NULL, (long) argcAddr));
printf("3. argc = %d\n", read2(NULL, (long) argcAddr));
}
=====================================
-Doug
On Mar 12, 2014, at 2:30 AM, Christian Thalinger <christian.thalinger at oracle.com> wrote:
>
> On Mar 11, 2014, at 4:01 PM, Tom Rodriguez <tom.rodriguez at oracle.com> wrote:
>
>> So this is a known clang/llvm issue? Has it been reported?
>
> I don’t think so. At least I didn’t do it.
>
>>
>> tom
>>
>> On Mar 11, 2014, at 3:14 PM, Christian Thalinger <christian.thalinger at oracle.com> wrote:
>>
>>> Sigh. Meta-circular FTW! ;-)
>>>
>>> Did you add a new section like this:
>>>
>>> # Clang 5.0
>>> ifeq ($(shell expr $(CC_VER_MAJOR) = 5 \& $(CC_VER_MINOR) = 0), 1)
>>> OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
>>> OPT_CFLAGS/unsafe.o += -O1
>>> OPT_CFLAGS/graalCompilerToVM.o += -O1
>>> endif
>>>
>>> for 5.1 in make/bsd/makefiles/gcc.make?
>>>
>>> On Mar 11, 2014, at 3:03 PM, Doug Simon <doug.simon at oracle.com> wrote:
>>>
>>>> Since I have automatic updating enabled on my Mac, I was recently updated to the latest version of Xcode (5.1). I have just done my first recompile of HotSpot since this update and am seeing that clang appears to have a rather serious bug. In both disassembled functions below, the third parameter (%rdx) is a jobject that should be resolved via JNIHandles::resolve and then dereferenced *after* adding the fourth parameter (%rcx) to it. clang is inlining the call to JNIHandles::resolve but omitting the null check on the jobject value.
>>>>
>>>> If this is really a bug, I’m sure reports about it will start showing up soon. In the meantime, don’t update Xcode.
>>>>
>>>> -Doug
>>>>
>>>>
>>>> _Unsafe_GetLong:
>>>> 0000000000357e59 pushq %rbp
>>>> 0000000000357e5a movq %rsp, %rbp
>>>> 0000000000357e5d pushq %r15
>>>> 0000000000357e5f pushq %r14
>>>> 0000000000357e61 pushq %r12
>>>> 0000000000357e63 pushq %rbx
>>>> 0000000000357e64 subq $0x10, %rsp
>>>> 0000000000357e68 movq %rcx, %r14
>>>> 0000000000357e6b movq %rdx, %r15
>>>> 0000000000357e6e movq %rdi, %rbx
>>>> 0000000000357e71 movl 0x90(%rbx), %eax
>>>> 0000000000357e77 addq $-0x1f0, %rbx
>>>> 0000000000357e7e cmpl $0xdeab, %eax
>>>> 0000000000357e83 je 0x357e9c
>>>> 0000000000357e85 movl 0x280(%rbx), %eax
>>>> 0000000000357e8b cmpl $0xdeac, %eax
>>>> 0000000000357e90 je 0x357e9c
>>>> 0000000000357e92 movq %rbx, %rdi
>>>> 0000000000357e95 callq __ZN10JavaThread18block_if_vm_exitedEv
>>>> 0000000000357e9a xorl %ebx, %ebx
>>>> 0000000000357e9c leaq -0x28(%rbp), %r12
>>>> 0000000000357ea0 movq %r12, %rdi
>>>> 0000000000357ea3 movq %rbx, %rsi
>>>> 0000000000357ea6 callq __ZN20ThreadInVMfromNativeC1EP10JavaThread
>>>> 0000000000357eab movq %rbx, -0x30(%rbp)
>>>> 0000000000357eaf movq (%r15), %rax
>>>> 0000000000357eb2 movq (%rax,%r14), %rbx
>>>> 0000000000357eb6 leaq -0x30(%rbp), %rdi
>>>> 0000000000357eba callq __ZN17HandleMarkCleanerD1Ev
>>>> 0000000000357ebf movq %r12, %rdi
>>>> 0000000000357ec2 callq __ZN20ThreadInVMfromNativeD1Ev
>>>> 0000000000357ec7 movq %rbx, %rax
>>>> 0000000000357eca addq $0x10, %rsp
>>>> 0000000000357ece popq %rbx
>>>> 0000000000357ecf popq %r12
>>>> 0000000000357ed1 popq %r14
>>>> 0000000000357ed3 popq %r15
>>>> 0000000000357ed5 popq %rbp
>>>> 0000000000357ed6 ret
>>>>
>>>> __Z33c2v_readUnsafeUncompressedPointerP7JNIEnv_P8_jobjectS2_l:
>>>> 000000000016e261 pushq %rbp
>>>> 000000000016e262 movq %rsp, %rbp
>>>> 000000000016e265 pushq %r15
>>>> 000000000016e267 pushq %r14
>>>> 000000000016e269 pushq %r12
>>>> 000000000016e26b pushq %rbx
>>>> 000000000016e26c subq $0x10, %rsp
>>>> 000000000016e270 movq %rcx, %r14
>>>> 000000000016e273 movq %rdx, %r15
>>>> 000000000016e276 leaq _TraceGraal(%rip), %rax
>>>> 000000000016e27d cmpq $0x3, (%rax)
>>>> 000000000016e281 jl 0x16e2ac
>>>> 000000000016e283 leaq _tty(%rip), %rbx
>>>> 000000000016e28a movq (%rbx), %rdi
>>>> 000000000016e28d leaq 0x23de25(%rip), %rsi ## literal pool for: " TraceGraal-3: "
>>>> 000000000016e294 xorl %eax, %eax
>>>> 000000000016e296 callq __ZN12outputStream5printEPKcz
>>>> 000000000016e29b movq (%rbx), %rdi
>>>> 000000000016e29e leaq 0x23ef0f(%rip), %rsi ## literal pool for: "CompilerToVM::readUnsafeUncompressedPointer"
>>>> 000000000016e2a5 xorl %eax, %eax
>>>> 000000000016e2a7 callq __ZN12outputStream8print_crEPKcz
>>>> 000000000016e2ac leaq __ZN18ThreadLocalStorage13_thread_indexE(%rip), %rax
>>>> 000000000016e2b3 movslq (%rax), %rdi
>>>> 000000000016e2b6 callq 0x38a758 ## symbol stub for: _pthread_getspecific
>>>> 000000000016e2bb movq %rax, %rbx
>>>> 000000000016e2be leaq -0x28(%rbp), %r12
>>>> 000000000016e2c2 movq %r12, %rdi
>>>> 000000000016e2c5 movq %rbx, %rsi
>>>> 000000000016e2c8 callq __ZN20ThreadInVMfromNativeC1EP10JavaThread
>>>> 000000000016e2cd movq %rbx, -0x30(%rbp)
>>>> 000000000016e2d1 movq (%r15), %rax
>>>> 000000000016e2d4 movq (%rax,%r14), %rdi
>>>> 000000000016e2d8 callq __ZN10JNIHandles10make_localEP7oopDesc
>>>> 000000000016e2dd movq %rax, %rbx
>>>> 000000000016e2e0 leaq -0x30(%rbp), %rdi
>>>> 000000000016e2e4 callq __ZN17HandleMarkCleanerD1Ev
>>>> 000000000016e2e9 movq %r12, %rdi
>>>> 000000000016e2ec callq __ZN20ThreadInVMfromNativeD1Ev
>>>> 000000000016e2f1 movq %rbx, %rax
>>>> 000000000016e2f4 addq $0x10, %rsp
>>>> 000000000016e2f8 popq %rbx
>>>> 000000000016e2f9 popq %r12
>>>> 000000000016e2fb popq %r14
>>>> 000000000016e2fd popq %r15
>>>> 000000000016e2ff popq %rbp
>>>> 000000000016e300 ret
>>>>
>>>>
>>>
>>
>
More information about the graal-dev
mailing list