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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With