Context is developing an android app that uses several static executable binaries through sh
syscall. One of the binaries eventually segfaults when using a samsung galaxy s4 cellphone (but not when using emulator or a Sony Xperia tipo cellphone), so following http://embetek.blogspot.com.es/2011/10/valgrind-for-arm.html with several custom modifications (CFLAGS='-static -march=armv7-a') end up getting a
$ ldd valgrind
not a dynamic executable
$ file valgrind
valgrind: ELF 32-bit LSB executable, ARM, version 1 (SYSV),
statically linked, for GNU/Linux 3.2.0, not stripped.
Loaded on the target phone (versioned android 4.2.2 kernel 3.4...), (context.getFilesDir() + File.separator + "valgrind").canExecute()
returns false.
Running sh -c PATH...valgrind
tells valgrind: can't execute: Permission denied
and status 126 on exit.
Emulator seems to run kernel 2.6... so there adb shell
and executing valgrind
there told something similar but more decorated telling about a kernel version mismatch: literally
llostatic/files/valgrind <
FATAL: kernel too old
Segmentation fault
(context.getFilesDir() + File.separator + "valgrind").setExecute()
is failing by unknown reason was failing because it wasn't being done at all (was doing something like dumpAssetToFile("valgrind"){/* Many things suppressed here. */ argument.setExecute() /* Done wrong without a files dir path ask */}
.
Now valgrind
seems to be correctly calling for a memcheck-arm-linux
, but I didn't yet made it recognize it.
Even a execution of "sh -c \"PATH=$PATH:" + getFilesDir() + File.separator + " " + getFilesDir() + File.separator + "busybox strace valgrind -v " + BINARY + " " + ARGS + " " + "2>&1\""
does not do what I expect. It is not exactly this what gets executed, but am outputting this to stderr.
W/System.err(6918): commandStrArr[0]: sh
W/System.err(6918): commandStrArr[1]: -c
W/System.err(6918): commandStrArr[2]: PATH=$PATH:/data/data/NAMESPACE/files/ busy
box strace valgrind -v /data/data/NAMESPACE/files/BINARY ARGS 2>&1
W/System.err(6918): strace: applet not found
W/System.err(6918): valgrind: failed to start tool 'memcheck' for platform 'arm-l
inux': No such file or directory
W/System.err(6918): Error: BINARY exited with status nonzero (1).
My read of this is that busybox
can not emulate strace
, but is anyway executing as a command and args from what it thinks as args[2] to the end of its view of arguments. valgrind
is loading well but can not find memcheck
. A context here is memcheck-arm-linux
is an asset' ed static binary dumped to the files directory together with those working valgrind
and busybox
. I can not be able to be sure memcheck-arm-linux
is exactly what is asking for, if I can't get a system calls trace. IMHO It would be a gotcha not being memcheck-arm-linux
what valgrind
is calling here "'memcheck' for platform 'arm-linux'".
Additional info (abstract the cwds please):
$ file busybox
busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for
GNU/Linux 3.2.0, stripped
[...]
$ file coregrind/valgrind
coregrind/valgrind: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically
linked, for GNU/Linux 3.2.0, not stripped
[...]
$ file memcheck/memcheck-arm-linux
memcheck/memcheck-arm-linux: ELF 32-bit LSB executable, ARM, version 1 (SYSV), st
atically linked, not stripped
Does anybody see why valgrind
seems no to be accepting memcheck-arm-linux
as a valid memcheck
tool?
Finally strace
gave solution to this problem.
Don't still have the trace, but strace
told very clearly that valgrind
was calling memcheck-arm-linux
with a wrong path. Was looking some path from the host compiler machine that obviously don't exist in the target machine.
That hinted the valgrind
build command should be changed from
$ export CROSS_COMPILE=arm-unknown-linux-gnueabi- && export CC=${CROSS_COMPILE}gc
c && export CPP=${CROSS_COMPILE}cpp && export CXX=${CROSS_COMPILE}g++ && export L
D=${CROSS_COMPILE}ld && export AR=${CROSS_COMPILE}ar && ./configure --target=arm-
unknown-linux-gnueabi --host=armv7a-none-linux-gnueabi --prefix=$HOME/valgrind-3.
6.1/construct CFLAGS='-static -march=armv7-a' -verbose 2>&1 && make clean && make
-j4 && make
to:
$ export CROSS_COMPILE=arm-unknown-linux-gnueabi- && export CC=${CROSS_COMPILE}gc
c && export CPP=${CROSS_COMPILE}cpp && export CXX=${CROSS_COMPILE}g++ && export L
D=${CROSS_COMPILE}ld && export AR=${CROSS_COMPILE}ar && ./configure --target=arm-
unknown-linux-gnueabi --host=armv7a-none-linux-gnueabi --prefix=/data/data/$APK_P
ACKAGE_NAMESPACE/files CFLAGS='-static -march=armv7-a' -verbose 2>&1 && make clea
n && make -j4 && make
You can see --prefix
is now correctly set to a path that exists in the target device, and is valid. Hardcoded. Dirty. Ugly. But is working now.
来源:https://stackoverflow.com/questions/19121524/getting-a-valgrind-for-android-problems-with-valgrinds-looking-for-memcheck