|
From: Jack H. <ho...@br...> - 2012-03-03 02:51:15
|
I ran into a backend codegen issue (radr://10942455, "valgrind's memcheck-x86-darwin i386 static binary misbuilt by clang") which the Apple compiler developers are looking at. This also resides in llvm.org as http://llvm.org/bugs/show_bug.cgi?id=12125. The radar details are... ------------------------------------------------------------------------------------------------------------------------------- 27-Feb-2012 08:30 PM Jack Howarth: Summary: The i386 static binary for memcheck-x86-darwin in valgrind 3.7.0 segfaults when built with clang from either Xcode 4.2 on darwin10 or Xcode 4.3 on darwin11 and linked with -new_linker. The same static binary when built with llvm-gcc-4.2 from either Xcode 4.2 on darwin10 or Xcode 4.3 on darwin11 and linked with -new_linker doesn't crash. Steps to Reproduce: 1) extract the attached memcheck_clang.tar.bz2 2) execute "./memcheck-x86-darwin" which will reproduce the segmentation fault. 3) execute the "bad_link" shell script to reproduce the linkage of memcheck-x86-darwin. /usr/bin/ld -static -new_linker -arch i386 -macosx_version_min 10.5 -o memcheck-x86-darwin -u __start -e __start -image_base 0x38000000 -stack_addr 0x34000000 -stack_size 0x800000 memcheck_x86_darwin-mc_leakcheck.o memcheck_x86_darwin-mc_malloc_wrappers.o memcheck_x86_darwin-mc_main.o memcheck_x86_darwin-mc_translate.o memcheck_x86_darwin-mc_machine.o memcheck_x86_darwin-mc_errors.o libcoregrind-x86-darwin.a libvex-x86-darwin.a Expected Results: I expected the clang built "memcheck-x86-darwin" i386 static executable to execute like the llvm-gcc built one and produce the output... valgrind: You cannot run './memcheck-x86-darwin' directly. valgrind: You should use $prefix/bin/valgrind. Note that the attached memcheck_llvm-gcc.tar.bz2 can be used to reproduce the llvm-gcc linkage of memcheck-x86-darwin executable with the provided "good_link" shell script as... /usr/bin/ld -static -new_linker -arch i386 -macosx_version_min 10.5 -o memcheck-x86-darwin -u __start -e __start -image_base 0x38000000 -stack_addr 0x34000000 -stack_size 0x800000 memcheck_x86_darwin-mc_leakcheck.o memcheck_x86_darwin-mc_malloc_wrappers.o memcheck_x86_darwin-mc_main.o memcheck_x86_darwin-mc_translate.o memcheck_x86_darwin-mc_machine.o memcheck_x86_darwin-mc_errors.o libcoregrind-x86-darwin.a libvex-x86-darwin.a Actual Results: For the clang build... gdb ./memcheck-x86-darwin GNU gdb 6.3.50-20050815 (Apple version gdb-1752) (Sat Jan 28 03:02:46 UTC 2012) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-apple-darwin"... warning: UUID mismatch detected between: /Users/howarth/memcheck_clang/memcheck-x86-darwin /Users/howarth/memcheck_clang/memcheck-x86-darwin.dSYM/Contents/Resources/DWARF/memcheck-x86-darwin... (gdb) set disable-aslr off (gdb) r Starting program: /Users/howarth/memcheck_clang/memcheck-x86-darwin Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x00000000 valgrind_main () at m_main.c:1435 1435 struct vki_rlimit zero = { 0, 0 }; (gdb) bt #0 valgrind_main () at m_main.c:1435 #1 0x38038879 in _start_in_C_darwin (pArgc=0x33fff888) at m_main.c:2898 Current language: auto; currently minimal (gdb) Regression: Notes: The x86_64 static binary for the memcheck-amd64-darwin works fine when built with clang or llvm-gcc. 27-Feb-2012 07:19 PM Jack Howarth: This issue occurs with all of the static utility programs built for i386 when using clang. This includes cachegrind-x86-darwin, callgrind-x86-darwin, drd-x86-darwin, exp-bbv-x86-darwin, exp-dhat-x86-darwin, exp-sgcheck-x86-darwin, helgrind-x86-darwin, lackey-x86-darwin, massif-x86-darwin, memcheck-x86-darwin and none-x86-darwin. So additional test cases can be provided if necessary. 28-Feb-2012 06:35 PM Jack Howarth: Rebuilding valgrind with clang at -O0 eliminates the crashes in static executables like memcheck-x86-darwin. Further analysis shows that the code in memcheck-x86-darwin which needs to be compiled at -O0 is in libcoregrind-x86-darwin.a. I will attempt to pinpoint the exact object file in libcoregrind-x86-darwin.a that is being miscomputed at -O1 and above. 28-Feb-2012 08:37 PM Jack Howarth: The problem is that clang miscompiles coregrind/m_main.c at optimizations higher than -O0. I have attached a preprocessed source file, m_main.i, and an assembly file, m_main.s.O1, file generated with... # /usr/bin/clang -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I../VEX/pub -DVGA_x86=1 -DVGO_darwin=1 -DVGP_x86_darwin=1 -DVGPV_x86_darwin_vanilla=1 -I../coregrind -DVG_LIBDIR="\"/sw/lib/valgrind"\" -DVG_PLATFORM="\"x86-darwin\"" -I/sw/include -arch i386 -O2 -g -Wall -Wmissing-prototypes -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations -Wno-format-zero-length -fno-strict-aliasing -fno-builtin -mmacosx-version-min=10.5 -fno-stack-protector -fno-pic -fno-PIC -Wno-long-long -g -O1 -Wno-pointer-sign -fno-stack-protector -c -o libcoregrind_x86_darwin_a-m_main.o m_main.c --save-temps clang: warning: argument unused during compilation: '-fno-pic' clang: warning: argument unused during compilation: '-fno-PIC' In file included from m_main.c:1: m_main.c:2000:42: warning: comparison of unsigned expression >= 0 is always true [-Wtautological-compare] ((void) (__builtin_expect(!!(tid_main >= 0 && tid_main < 500 && tid_main != ((ThreadId)(0))), 1) ? 0 : (vgPlain_assert_fail ( ((Bool)1), "tid_main ... ~~~~~~~~ ^ ~ 1 warning generated. as well as an assembly file, m_main.s.O0 generated with... # /usr/bin/clang -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I../VEX/pub -DVGA_x86=1 -DVGO_darwin=1 -DVGP_x86_darwin=1 -DVGPV_x86_darwin_vanilla=1 -I../coregrind -DVG_LIBDIR="\"/sw/lib/valgrind"\" -DVG_PLATFORM="\"x86-darwin\"" -I/sw/include -arch i386 -O2 -g -Wall -Wmissing-prototypes -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations -Wno-format-zero-length -fno-strict-aliasing -fno-builtin -mmacosx-version-min=10.5 -fno-stack-protector -fno-pic -fno-PIC -Wno-long-long -g -O0 -Wno-pointer-sign -fno-stack-protector -c -o libcoregrind_x86_darwin_a-m_main.o m_main.c --save-temps clang: warning: argument unused during compilation: '-fno-pic' clang: warning: argument unused during compilation: '-fno-PIC' In file included from m_main.c:1: m_main.c:2000:42: warning: comparison of unsigned expression >= 0 is always true [-Wtautological-compare] ((void) (__builtin_expect(!!(tid_main >= 0 && tid_main < 500 && tid_main != ((ThreadId)(0))), 1) ? 0 : (vgPlain_assert_fail ( ((Bool)1), "tid_main ... ~~~~~~~~ ^ ~ 1 warning generated. ------------------------------------------------------------------------------------------------------------ The Apple programmer looking at this potential clang/llvm backend bug asks the followin question in http://llvm.org/bugs/show_bug.cgi?id=12125#c9... The valgrind-3.7.0 sources have this ASM code at the top of the m_main.c file: .text .align 2,0x90 .globl __start __start: movl $_vgPlain_interim_stack, %eax addl $8192, %eax addl $(4096 * 256), %eax subl $16, %eax andl $~15, %eax xchgl %eax, %esp pushl %eax call __start_in_C_darwin int $3 int $3 Two things concern me here. First, clang doesn't support the `-fno-pic' flag. This code is obviously wanting the code to be static on Darwin (see the absolute reference to vgPlain_interim_stack). It's possible that dyld is moving things around and the reference to the stack is now off. (This might explain some of the problems I've been seeing on one machine.) Second, the "push %eax" at the end could mess up the stack that they've gone through pains to align to 16-bytes. In particular, it will make it off by 4 bytes. Could you check with the valgrind guys to see what they have to say about this? Did they compile their version of valgrind with clang or llvm-gcc? Etc. Any comments? Jack ps I don't see this issue on the i386 static executables of valgrind 3.7.0 built with clang svn on x86_64 Linux. |