3

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?

1737973
  • 159
  • 18
  • 42
  • 1
    This may be an execute permission issue and/or ownership issue. The permissions of an executable need to be read+execute for the owner. Could you check if the installation ensures this. Run `sh -c "ls -l PATH_TO_VALGRIND"` to check if things are sane. – Samveen Oct 02 '13 at 09:22
  • Although the `valgrind` deployment methodology was somewhat 90% the same as the `valgrind`ed program deployment methodology, execute permission was not set when me looked for it through `adb shell` into the emulator (cellphone is currently away). Will recheck all that Java code and come back giving more feedback. – 1737973 Oct 02 '13 at 10:50
  • My fault: now my Java code is fixed and app is correctly outputting `valgrind: failed to start tool 'memcheck' for platform 'arm-linux': No such file or directory` and returning a status 1. I tried to vote me down. – 1737973 Oct 02 '13 at 14:01
  • Better still, add the erroneous java code into the question and add an answer with what you did to fix the java code. – Samveen Oct 03 '13 at 05:27
  • I was embarrasingly missing the path to `valgrind` in the `setExecutable(...)` call. But now am not being able to get `valgrind` to use the (_existing_) `memcheck-arm-linux`. So I was thinking of passing a `busybox` if it was able to do `strace` invocations. – 1737973 Oct 03 '13 at 07:24
  • You'll need strace for android. Loads available on XDA-Developers. – Samveen Oct 03 '13 at 09:47
  • Dont' get me wrong but if you mean 'xda-developers.com' am sorry that seems a fan portal with no code nor _untrustable_ prebuilts. Isn't it better cloning strace from SourceForge the classic way? – 1737973 Oct 03 '13 at 10:19
  • You can build it yourself(that's what I did). Most trusted people on XDA do link in references to their code bases and instructions for people to verify or follow, as building strace with the NDK is not an easy n quick job. – Samveen Oct 06 '13 at 04:21

1 Answers1

3

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.

1737973
  • 159
  • 18
  • 42
  • What did you do for strace? Built it yourself, or used a precompiled binary? – Samveen Dec 04 '13 at 00:13
  • I did `$ export CC=MY_GCC_TOOLCHAIN_CC && export CPP=MY_GCC_TOOLCHAIN_CPP && export CFLAGS='-I/PATH/TO/MY_GCC_TOOLCHAIN_SYSROOT/usr/include' && export LDFLAGS='-L/PATH/TO/MY_GCC_TOOLCHAIN_SYSROOT/usr/lib -static' && ./configure --host=arm && make clean && make VERBOSE=1 -j JOBS_NO 2>&1 && cp strace strace_g_static && cp strace_g_static strace_static && MY_GCC_TOOLCHAIN_STRIP strace_static` from the base folder of a pretty standard strace, (`git remote -v` is showing git://git.code.sf.net/p/strace/code as origin) – 1737973 Dec 05 '13 at 07:34
  • I finally recorded and [uploaded](http://youtu.be/4UXe6P6xUbY) to YouTube a small video of the app that uses all these statically linked C/C++ programs. – 1737973 Nov 10 '16 at 06:03