[llvm-dev] OpenJDK8 failed to work after compiled by LLVM 8 for X86 (original) (raw)
Anton Korobeynikov via llvm-dev llvm-dev at lists.llvm.org
Wed Sep 12 05:38:18 PDT 2018
- Previous message: [llvm-dev] OpenJDK8 failed to work after compiled by LLVM 8 for X86
- Next message: [llvm-dev] linear-scan RA
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
The code in question has an undefined behavior per C++ standard. And the transformation is certainly valid.
On Wed, Sep 12, 2018 at 2:55 PM, Leslie Zhai via llvm-dev <llvm-dev at lists.llvm.org> wrote:
Hi Martin,
Thanks for your response!
在 2018年09月12日 19:47, Martin Buchholz 写道:
I tend to think that clang's optimization was valid, and if placing data into .rodata has any value at all (why else does .rodata exist?) placing data into .rodata is not wrong! But it needs to double check the setter of isReadOnly() if condition in the llvm/lib/Analysis/MemoryDependenceAnalysis.cpp and llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thanks, Leslie Zhai then the optimization is valuable. On Wed, Sep 12, 2018 at 4:10 AM, Leslie Zhai <zhaixiang at loongson.cn> wrote:
Reported https://bugs.llvm.org/showbug.cgi?id=38911 Thanks, Leslie Zhai
在 2018年09月11日 16:55, Dimitry Andric 写道: Hi Leslie, The problem really lies in the OpenJDK code, as it is attempting to write to a const object. If this seems to work with certain compiler(s) and optimization settings, it is just luck. :-) Here is a reduced example, which shows the issue: ====================================================================== #include class NativeCallStack { public: static const NativeCallStack EMPTYSTACK; private: enum { DEPTH = 4 }; void* stack[DEPTH]; public: NativeCallStack() { for (int i = 0; i < DEPTH; ++i) {_ _stack[i] = nullptr;_ _}_ _}_ _};_ _const NativeCallStack NativeCallStack::EMPTYSTACK;_ _int main(void)_ _{_ _// The following should segfault, if EMPTYSTACK was placed into_ _.rodata._ _::new ((void*)&NativeCallStack::EMPTYSTACK) NativeCallStack();_ _return 0;_ _}_ _======================================================================_ _clang 7.0.0 rc2 produces this assembly:_ _.globl main # -- Begin function main_ _.p2align 4, 0x90_ _.type main, at function_ _main: # @main_ _.cfistartproc_ _# %bb.0: # %entry_ _pushq %rbp_ _.cfidefcfaoffset 16_ _.cfioffset %rbp, -16_ _movq %rsp, %rbp_ _.cfidefcfaregister %rbp_ _xorps %xmm0, %xmm0_ _movups %xmm0, NativeCallStack::EMPTYSTACK+16(%rip)_ _movups %xmm0, NativeCallStack::EMPTYSTACK(%rip)_ _xorl %eax, %eax_ _popq %rbp_ _.cfidefcfa %rsp, 8_ _retq_ _.Lfuncend0:_ _.size main, .Lfuncend0-main_ _.cfiendproc_ _# -- End function_ _.type NativeCallStack::EMPTYSTACK, at object #_ _@NativeCallStack::EMPTYSTACK_ _.section .rodata,"a", at progbits_ _.globl NativeCallStack::EMPTYSTACK_ _.p2align 3_ _NativeCallStack::EMPTYSTACK:_ _.zero 32_ _.size NativeCallStack::EMPTYSTACK, 32_ _The whole constructor has been optimized out, and EMPTYSTACK has been_ _replaced by .zero 32, placed in the .rodata segment, which is a_ _perfectly valid transformation._ _Then, in main(), an attempt is made to write to that read-only segment,_ _which will usually segfault, depending on how strictly the underlying_ _operating system enforces these protections._ _In contrast, gcc 8.2.0 produces:_ _.globl main_ _.type main, @function_ _main:_ _.LFB74:_ _.cfistartproc_ _movq $0, NativeCallStack::EMPTYSTACK(%rip)_ _xorl %eax, %eax_ _movq $0, NativeCallStack::EMPTYSTACK+8(%rip)_ _movq $0, NativeCallStack::EMPTYSTACK+16(%rip)_ _movq $0, NativeCallStack::EMPTYSTACK+24(%rip)_ _ret_ _.cfiendproc_ _.LFE74:_ _.size main, .-main_ _.p2align 4,,15_ _.type GLOBAL_subI_ZN15NativeCallStack11EMPTYSTACKE,_ _@function_ _GLOBAL_subI_ZN15NativeCallStack11EMPTYSTACKE:_ _.LFB76:_ _.cfistartproc_ _movq $0, NativeCallStack::EMPTYSTACK(%rip)_ _movq $0, NativeCallStack::EMPTYSTACK+8(%rip)_ _movq $0, NativeCallStack::EMPTYSTACK+16(%rip)_ _movq $0, NativeCallStack::EMPTYSTACK+24(%rip)_ _ret_ _.cfiendproc_ _.LFE76:_ _.size GLOBAL_subI_ZN15NativeCallStack11EMPTYSTACKE,_ _.-GLOBAL_subI_ZN15NativeCallStack11EMPTYSTACKE_ _.section .ctors,"aw", at progbits_ _.align 8_ _.quad GLOBAL_subI_ZN15NativeCallStack11EMPTYSTACKE_ _.globl NativeCallStack::EMPTYSTACK_ _.bss_ _.align 32_ _.type NativeCallStack::EMPTYSTACK, @object_ _.size NativeCallStack::EMPTYSTACK, 32_ _NativeCallStack::EMPTYSTACK:_ _.zero 32_ _Here you can see that gcc decided to not place EMPTYSTACK in .rodata,_ _but in .bss, which is read/write. It adds the global constructor to_ _the .ctors section, so the dynamic linker is made responsible for_ _calling it._ _Note that now the EMPTYSTACK object is unnecessarily initialized twice,_ _once by the global constructor, and once in main._ _-Dimitry_ _On 11 Sep 2018, at 03:38, Leslie Zhai <zhaixiang at loongson.cn> wrote: Hi Dimitry, Thanks for your kind response! Thanks for the commit message of Jung's patch, I found that the bug had been fixed in OpenJDK 12 by Zhengyu https://bugs.openjdk.java.net/browse/JDK-8205965 But only backported to 11. So Jung could backport it for OpenJDK 8, thanks a lot! But I argue that the root cause might be in the compiler side, why clang-3.9.1, gcc-6.4.1 couldn't reproduce the bug? And it might be work for clang-4.0 https://bugs.openjdk.java.net/browse/JDK-8208494 I will test LLVM 5 to check out whether or not reproducible.
在 2018年09月11日 00:59, Dimitry Andric 写道: Hi Leslie, This is likely the same problem as was reported in https://bugs.freebsd.org/225054#c8, and fixed by the following patch:
https://svnweb.freebsd.org/ports/head/java/openjdk8/files/patch-hotspotsrcsharevmservicesmemTracker.cpp?view=markup&pathrev=459368 Can you please try that out, and see if it fixes it for you too? -Dimitry On 10 Sep 2018, at 18:20, Leslie Zhai via llvm-dev <llvm-dev at lists.llvm.org> wrote: Hi all, OpenJDK8 jdk8u-dev[1] is just able to work after compiled with LLVM 3.9.1 for X86: $ ./build/linux-x8664-normal-server-slowdebug/images/j2sdk-image/bin/java -version openjdk version "1.8.0-internal-debug" OpenJDK Runtime Environment (build 1.8.0-internal-debug-xiangzhai201809092108-b00) OpenJDK 64-Bit Server VM (build 25.71-b00-debug, mixed mode) $ strings ./build/linux-x8664-normal-server-slowdebug/images/j2sdk-image/bin/java | grep clang clang version 3.9.1 (tags/RELEASE391/final) But it failed to work after compiled with LLVM 8 for X86: $ ./build/linux-x8664-normal-server-fastdebug/images/j2sdk-image/bin/java -version Segmentation fault $ gdb --ex run --args ./build/linux-x8664-normal-server-fastdebug/images/j2sdk-image/bin/java -version GNU gdb (GDB) Fedora 7.12.1-48.fc25 ... Starting program: /home/xiangzhai/project/jdk8u-llvm/build/linux-x8664-normal-server-fastdebug/images/j2sdk-image/bin/java -version [Thread debugging using libthreaddb enabled] Using host libthreaddb library "/lib64/libthreaddb.so.1". Program received signal SIGSEGV, Segmentation fault. [ Legend: Modified register | Code | Heap | Stack | String ] ───────────────────────────────────────────────────────────────────────────────────────────────[ registers ]──── $rax : 0x0 $rbx : 0x0 $rcx : 0x7ffff7315eb0 → 0x00007ffff6ae30a0 → NativeCallStack::printon(outputStream*)+0 xor edx, edx $rdx : 0x0 $rsp : 0x7fffffff9328 → 0x00007ffff6a76822 → MemTracker::inittrackinglevel()+178 mov edi, ebx $rbp : 0x7fffffff93c0 → 0x00007fffffff94f0 → 0x00007fffffff9510 → 0x0000000000000002 $rsi : 0x0 $rdi : 0x7ffff7315e70 → 0x00007ffff7315eb0 → 0x00007ffff6ae30a0 → NativeCallStack::printon(outputStream*)+0 xor edx, edx $rip : 0x7ffff6ae2f5b → NativeCallStack::NativeCallStack(int,+0 mov QWORD PTR [rdi], rcx $r8 : 0x1 $r9 : 0xf $r10 : 0x64 $r11 : 0x0 $r12 : 0x7fffffffdc88 → 0x00007fffffffe04c → "/home/xiangzhai/project/jdk8u-llvm/build/linux-x86[...]" $r13 : 0x7fffffffdca0 → 0x00007fffffffe0bf → "XDGVTNR=1" $r14 : 0x7fffffff9330 → "NMTLEVEL10535" $r15 : 0x6 $eflags: [carry parity adjust zero sign trap INTERRUPT direction overflow RESUME virtualx86 identification] $ss: 0x002b ds:0x0000ds: 0x0000 ds:0x0000cs: 0x0033 es:0x0000es: 0x0000 es:0x0000gs: 0x0000 $fs: 0x0000 ───────────────────────────────────────────────────────────────────────────────────────────────────[ stack ]──── 0x00007fffffff9328│+0x00: 0x00007ffff6a76822 → MemTracker::inittrackinglevel()+178 mov edi, ebx ← $rsp 0x00007fffffff9330│+0x08: "NMTLEVEL10535" ← $r14 0x00007fffffff9338│+0x10: 0x0035333530315f4c ("L10535"?) 0x00007fffffff9340│+0x18: 0x0000000000000001 0x00007fffffff9348│+0x20: 0x0000000000602190 → 0x00007ffff5eb7000 → 0x00010102464c457f 0x00007fffffff9350│+0x28: 0x0000000000000004 0x00007fffffff9358│+0x30: 0x000000066474e551 0x00007fffffff9360│+0x38: 0x0000000000000000 ────────────────────────────────────────────────────────────────────────────────────────[ code:i386:x86-64 ]──── 0x7ffff6ae2f4b <printownedlocksonerror(outputStream*)+187> add eax, 0x1f0f00 0x7ffff6ae2f50 NativeCallStack::NativeCallStack(int,+0 mov rcx, QWORD PTR [rip+0x842781] # 0x7ffff73256d8 0x7ffff6ae2f57 NativeCallStack::NativeCallStack(int,+0 add rcx, 0x10 → 0x7ffff6ae2f5b NativeCallStack::NativeCallStack(int,+0 mov QWORD PTR [rdi], rcx 0x7ffff6ae2f5e NativeCallStack::NativeCallStack(int,+0 mov DWORD PTR [rdi+0x28], 0x0 0x7ffff6ae2f65 NativeCallStack::NativeCallStack(int,+0 add rdi, 0x8 0x7ffff6ae2f69 NativeCallStack::NativeCallStack(int,+0 test edx, edx 0x7ffff6ae2f6b NativeCallStack::NativeCallStack(int,+0 je 0x7ffff6ae2f7b <NativeCallStack::NativeCallStack(int, bool)+43> 0x7ffff6ae2f6d NativeCallStack::NativeCallStack(int,+0 mov eax, esi ─────────[ source:/home/xiangzhai/project/jdk8u-llvm/hotspot/src/share/vm/utilities/nativeCallStack.cpp+33 ]──── 28 #include "utilities/nativeCallStack.hpp" 29 30 const NativeCallStack NativeCallStack::EMPTYSTACK(0, false); 31 32 NativeCallStack::NativeCallStack(int toSkip, bool fillStack) : → 33 hashvalue(0) { 34 35 #if !PLATFORMNATIVESTACKWALKINGSUPPORTED 36 fillStack = false; 37 #endif 38 ─────────────────────────────────────────────────────────────────────────────────────────────────[ threads ]──── [#0] Id 1, Name: "java", stopped, reason: SIGSEGV ───────────────────────────────────────────────────────────────────────────────────────────────────[ trace ]──── [#0] 0x7ffff6ae2f5b → Name: NativeCallStack::NativeCallStack(this=0x7ffff7315e70 NativeCallStack::EMPTYSTACK, toSkip=0x0, fillStack=0x0) [#1] 0x7ffff6a76822 → Name: MemTracker::inittrackinglevel() [#2] 0x7ffff62eff49 → Name: MemTracker::trackinglevel() [#3] 0x7ffff62eff49 → Name: ResourceObj::operator new(size=0x20, type=ResourceObj::STACKOREMBEDDED, flags=) [#4] 0x7ffff61369ec → Name: GLOBAL_subIc1Greedy.cpp() [#5] 0x7ffff7de7d9a → Name: callinit(l=, argc=0x2, argv=0x7fffffffdc88, env=0x7fffffffdca0) [#6] 0x7ffff7de7eab → Name: callinit(env=0x7fffffffdca0, argv=0x7fffffffdc88, argc=0x2, l=) [#7] 0x7ffff7de7eab → Name: dlinit(mainmap=0x602190, argc=0x2, argv=0x7fffffffdc88, env=0x7fffffffdca0) [#8] 0x7ffff7dece46 → Name: dlopenworker(a=0x7fffffff97e0) [#9] 0x7ffff7de7c44 → Name: dlcatcherror(objname=0x7fffffff97d0, errstring=0x7fffffff97d8, mallocedp=0x7fffffff97cf, operate=0x7ffff7decae0 , args=0x7fffffff97e0) ──────────────────────────────────────────────────────────────────────────────────────────────────────────────── 0x00007ffff6ae2f5b in NativeCallStack::NativeCallStack (this=0x7ffff7315e70 NativeCallStack::EMPTYSTACK, toSkip=0x0, fillStack=0x0) at /home/xiangzhai/project/jdk8u-llvm/hotspot/src/share/vm/utilities/nativeCallStack.cpp:33 33 hashvalue(0) { gef➤ c Continuing. Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. gef➤ ----- 8< -------- 8< -------- 8< -------- 8< -------- 8< -------- 8< --- I started to use and contribute clang static analyzer[2] just for finding the bugs for open source software from LLVM 3.x, perhaps it is a bug of LLVM 8, because jdk8u is just able to print out '-version' after compiled with llvm-3.9.1, I will rebuild the LLVM 8 again, then rebuild jdk8u for triple check. 1. Workaround-compile-with-llvm.patch https://raw.githubusercontent.com/xiangzhai/jdk8u-dev/master/Workaround-compile-with-llvm.patch 2. https://github.com/llvm-mirror/clang/commit/a530e823ed2793ac149de7a984014e242a787682#diff-ff9160d4628cb9b6186559837c2c8668 3. The build option of LLVM 8 (bootstrap with LLVM 3.9.1): _cmake .. -DCMAKEBUILDTYPE=Release _ _-DCMAKECCOMPILER=clang _ _-DCMAKECXXCOMPILER=clang++ _ _-DCMAKECFLAGS="-fPIC" _ _-DCMAKECXXFLAGS="-std=c++11 -fPIC" _ _-DLLVMBUILDLLVMDYLIB=ON _ _-DLLVMLINKLLVMDYLIB=ON _ _-DLLVMINSTALLUTILS=ON _ _-DLLVMENABLERTTI=ON _ _-DLLVMENABLEFFI=ON _ _-DLLVMENABLEEH=ON _ _-DLLVMBUILDTESTS=ON _ _-DLLVMBUILDDOCS=OFF _ _-DLLVMENABLESPHINX=OFF _ _-DLLVMENABLEDOXYGEN=OFF _ _-DLLDBDISABLELIBEDIT=1 _ _-DSPHINXWARNINGSASERRORS=OFF _ _-DFFIINCLUDEDIR=$(pkg-config --variable=includedir libffi) _ -DFFILIBRARYDIR:PATH="$(pkg-config --variable=libdir libffi)" __ _-DLLVMBINUTILSINCDIR=/usr/include _ _-DLLVMLIBDIRSUFFIX=64 _ _-DLIBCXXENABLEABILINKERSCRIPT=ON _ _-DLIBUNWINDENABLESHARED=ON _ _-DLIBCXXABIUSELLVMUNWINDER=ON _ _-DLLDBTESTCCOMPILER=clang _ _-DLLDBTESTCXXCOMPILER=clang++ _ _-DLLVMDEFAULTTARGETTRIPLE="x8664-redhat-linux" _ -DCLANGVENDOR="LLVM China" 4. $ clang -v LLVM China clang version 8.0.0 (git at github.com:llvm-mirror/clang.git 81ef98628ebf5186d746c0986dcbf5073e842043) (git at github.com:llvm-mirror/llvm.git e1aac9723d55497e74d83d216329f08d9842e494) (based on LLVM 8.0.0svn) Target: x8664-redhat-linux Thread model: posix InstalledDir: /usr/bin Found candidate GCC installation: /usr/bin/../lib/gcc/i686-redhat-linux/6.4.1 Found candidate GCC installation: /usr/bin/../lib/gcc/x8664-redhat-linux/6.4.1 Found candidate GCC installation: /usr/lib/gcc/i686-redhat-linux/6.4.1 Found candidate GCC installation: /usr/lib/gcc/x8664-redhat-linux/6.4.1 Selected GCC installation: /usr/bin/../lib/gcc/x8664-redhat-linux/6.4.1 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Selected multilib: .;@m64 -- Regards, Leslie Zhai
LLVM Developers mailing list llvm-dev at lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -- Regards, Leslie Zhai
LLVM Developers mailing list llvm-dev at lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-- With best regards, Anton Korobeynikov Department of Statistical Modelling, Saint Petersburg State University
- Previous message: [llvm-dev] OpenJDK8 failed to work after compiled by LLVM 8 for X86
- Next message: [llvm-dev] linear-scan RA
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]