Valgrind for ARM needs extra support for tls (ThreadLocalStorage) in order to run valgrind tools for ARM apps under the android emulator for ARM on Linux x86 or x86_64. Without this extra support, then running any valgrind tool under the android emulator for ARM gets an immediate SIGSEGV. As diagnosed by Philippe Waroquiers, the android emulator claims that its CPU is armv7 except that it does not support tls. The string "tls" is missing from the Features that are listed by /proc/cpuinfo: ===== android emulator: *********************************************************** cat /proc/cpuinfo Processor : ARMv7 Processor rev 0 (v7l) BogoMIPS : 78.84 Features : swp half thumb fastmult vfp edsp neon vfpv3 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc08 CPU revision : 0 Hardware : Goldfish Revision : 0000 Serial : 0000000000000000 dual-core A9 in galaxy S 2: ********************************************************** # cat /proc/cpuinfo Processor : ARMv7 Processor rev 1 (v7l) processor : 0 BogoMIPS : 1592.52 Features : swp half thumb fastmult vfp edsp neon vfpv3 tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x2 CPU part : 0xc09 CPU revision : 1 Hardware : SMDK4210 Revision : 000e pandaboard: *********************************************************** $ cat /proc/cpuinfo Processor : ARMv7 Processor rev 2 (v7l) processor : 0 BogoMIPS : 596.46 processor : 1 BogoMIPS : 582.68 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x1 CPU part : 0xc09 CPU revision : 2 Hardware : OMAP4 Panda board Revision : 0020 Serial : 0000000000000000 ===== The fix is two short patches to svn-3.8.0, which will be attached. One patch adds a symbol in VEX, the other patch enhances dispatch-arm-linux.S. Reproducible: Always Steps to Reproduce: 1. adb shell # Android Debug Bridge (x86* tool which gives a shell in the emulated Android ARM environmentl) 2. /data/local/Inst/bin/valgrind --tool=none date Actual Results: ==511== Command: date ==511== [1] + Stopped (signal) ./valgrind --tool=none date # ==511== ==511== Process terminating with default action of signal 11 (SIGSEGV) ==511== Access not within mapped region at address 0x4004F4D0 ==511== at 0x481C754: __libc_preinit (in /system/lib/libc.so) ==511== If you believe this happened as a result of a stack ==511== overflow in your program's main thread (unlikely but ==511== possible), you can try to increase the size of the ==511== main thread stack using the --main-stacksize= flag. ==511== The main thread stack size used in this run was 8388608. Expected Results: No SIGSEGV.
Created attachment 72200 [details] GENOFFSET(ARM,arm,TPIDRURO)
Created attachment 72201 [details] enhance dispatch-arm-linux.S for CPU without tls hardware
Here is the code at the SIGSEGV; it's in the target app's libc.so: (gdb) x/9i __libc_preinit 0x1674c <__libc_preinit>: ldr r0, [pc, #20] ; (0x16764 <__libc_preinit+24>) ### r0= 0xffff0ff0 0x1674e <__libc_preinit+2>: movs r2, #0 0x16750 <__libc_preinit+4>: push {r4, lr} 0x16752 <__libc_preinit+6>: ldr r3, [r0, #0] ### r3= *(void **)0xffff0ff0 ***==>0x16754 <__libc_preinit+8>: ldr r0, [r3, #12] ### SIGSEGV here 0x16756 <__libc_preinit+10>: str r2, [r3, #12] 0x16758 <__libc_preinit+12>: bl 0x27c64 <__libc_init_common> 0x1675c <__libc_preinit+16>: bl 0x16160 <malloc_debug_init> 0x16760 <__libc_preinit+20>: pop {r4, pc} ### return (gdb) x/4x 0x16764 0x16764 <__libc_preinit+24>: 0xffff0ff0 0xe24dd008 0xe2102003 0xf5d0f000 Here is the approximate calling environment [it's old, but useful information]: http://nv-tegra.nvidia.com/gitweb/?p=android/platform/bionic.git;a=commitdiff_plain;h=b56b5659b3996e98c2060f168d1cff1474e77d2a +void __libc_prenit(void) +{ + /* Read the ELF data pointer form a special slot of the + * TLS area, then call __libc_init_common with it. + * + * Note that: + * - we clear the slot so no other initializer sees its value. + * - __libc_init_common() will change the TLS area so the old one + * won't be accessible anyway. + */ + void** tls_area = (void**)__get_tls(); + unsigned* elfdata = tls_area[TLS_SLOT_BIONIC_PREINIT]; + + tls_area[TLS_SLOT_BIONIC_PREINIT] = NULL; + + __libc_init_common(elfdata); +}
Created attachment 72206 [details] how to obtain and install adroid emulator Modified from original by Philippe Waroquiers. Note that android emulator is a 32-bit (i686) application. If you have a plain 64-bit x86_64 environment, then you will have to install some 32-bit packages. I got cryptic and unhelpful error messages before installing the 32-bit packages; I resorted to using strace to find some causes. On Fedora-17, the packages which I needed were: glibc.i686 ncurses-libs.i686 libgcc.i686 libstdc++.i686 zlib.i686 libXrender.i686 libXrandr.i686 libXext.i686 and their dependencies libXau.i686 libxcb.i686 libX11.i686
Fixed in revision 12710 Thanks for the problem analysis and solution. Note that after discussion, it was deemed better to not touch the asm dispatcher but rather execute the sys_set_tls syscall in the C code. At least for me, it worked similarly to the asm dispatcher changes.
I am still seeing what appears to be these symptoms using valgrind-3.8.1 for ARM Android. ~ # valgrind --tool=none date ==1674== Nulgrind, the minimal Valgrind tool ==1674== Copyright (C) 2002-2012, and GNU GPL'd, by Nicholas Nethercote. ==1674== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==1674== Command: date ==1674== [1]+ Stopped (signal) valgrind --tool=none date ~ # ==1674== ==1674== Process terminating with default action of signal 11 (SIGSEGV) ==1674== Access not within mapped region at address 0x0 ==1674== at 0xAFD26274: __libc_fini (in /system/lib/libc.so) ==1674== If you believe this happened as a result of a stack ==1674== overflow in your program's main thread (unlikely but ==1674== possible), you can try to increase the size of the ==1674== main thread stack using the --main-stacksize= flag. ==1674== The main thread stack size used in this run was 8388608. ==1674== Info for the board in question: ~ # cat /proc/cpuinfo Processor : ARMv7 Processor rev 2 (v7l) BogoMIPS : 597.64 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc08 CPU revision : 2 Hardware : Lectronix Georgetown Board Revision : 0020 Serial : 0000000000000000 Please advise if there is additional information that would be helpful or if there is something I can try.
The source code function assign_guest_tls() in file valgrind-3.8.1/coregrind/m_syswrap/syswrap-arm-linux.c must be built with: #define ANDROID_HARDWARE_emulator Did you do that?
No, I compiled with ANDROID_HARDWARE_generic, as my target is a custom ARM board, not the emulator.
(In reply to comment #8) > No, I compiled with ANDROID_HARDWARE_generic, as my target is a custom ARM > board, not the emulator. Compiled instances of valgrind are target-specific, and the android emulator is a different target. See the instructions in valgrind-3.8.1/README.android. (My position is that valgrind should detect at runtime the omission of 'tls' in the Features string from /proc/cpuinfo and adjust accordingly. Obviously the code does not do that.)
On Fri, Oct 5, 2012 at 10:26 AM, John Reiser <jreiser@bitwagon.com> wrote: > > (My position is that valgrind should detect at runtime the omission of > 'tls' in > the Features string from /proc/cpuinfo and adjust accordingly. Obviously > the > code does not do that.) > I assumed that would be how a fix would be implemented; obviously that was wrong on my part. I've been advised that our board actually does have tls enabled; it is just that /proc/cpuinfo was failing to report it. However, correcting that does not affect the problem.
(In reply to comment #10) > I've been advised that our board actually does have tls enabled; it is just > that /proc/cpuinfo was failing to report it. However, correcting that does > not affect the problem. It's the android emulator which removes 'tls' from the Features string. The emulator doesn't want to write the code to support "tls hardware".
On Fri, Oct 5, 2012 at 11:09 AM, John Reiser <jreiser@bitwagon.com> wrote: > https://bugs.kde.org/show_bug.cgi?id=302709 > > It's the android emulator which removes 'tls' from the Features string. > The > emulator doesn't want to write the code to support "tls hardware". > That makes sense re: the emulator. Patching my local copy of coregrind/m_syswrap/syswrap-arm-linux.c to include ANDROID_HARDWARE_generic in the #ifdef with ANDROID_HARDWARE_emulator appears to work for me.