-
Notifications
You must be signed in to change notification settings - Fork 70
TracerGrind on Android
See also valgrind-3.11.0/README.android
To cross-compile TracerGrind for Android:
Install first the usual TracerGrind dependencies on the host.
Then:
wget 'http://valgrind.org/downloads/valgrind-3.11.0.tar.bz2'
tar xf valgrind-3.11.0.tar.bz2
cp -r tracergrind valgrind-3.11.0/
patch -p0 < valgrind-3.11.0.diff
cd valgrind-3.11.0/
./autogen.sh
export NDKROOT=/path/to/your/android-ndk-r??
For ARM/AArch32:
export AR=$NDKROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar
export LD=$NDKROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld
export CC=$NDKROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
CPPFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm" \
CFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm" \
./configure --prefix=/data/local/Inst \
--host=armv7-unknown-linux --target=armv7-unknown-linux \
--with-tmpdir=/sdcard
For ARM64/AArch64:
export AR=$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar
export LD=$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld
export CC=$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc
CPPFLAGS="--sysroot=$NDKROOT/platforms/android-21/arch-arm64" \
CFLAGS="--sysroot=$NDKROOT/platforms/android-21/arch-arm64" \
./configure --prefix=/data/local/Inst \
--host=aarch64-unknown-linux --target=aarch64-unknown-linux \
--with-tmpdir=/sdcard
Then compiling:
make -j8
mkdir ../build
make install DESTDIR=$(pwd)/../build
This creates a ../build/data/local/Inst
If you use Adb Insecure, installation in /data/local/Inst/ is as easy as
adb push ../build /
/data/local/Inst/bin/valgrind --kernel-variant=android-gpu-adreno3xx \
--trace-children=yes \
--tool=tracergrind \
--filter=0x100000-0x200000 \
--vex-iropt-register-updates=allregs-at-mem-access \
--output=/sdcard/foo.trace mybin
Then as usual, on the host:
adb pull /sdcard/foo.trace .
sqlitetrace foo.trace foo.sqlite
tracegraph&
- ARM, NDK r10e, Android 4.4
- AArch64, NDK r10e, Android 5.1.1
- ARM, Nexus 6, NDK r11b, Android 6
- ARM, Nexus 4, NDK r11c, Android 4.4.4
- ARM, Galaxy Nexus, NDK r11c, Android 4.4.4 (Cyanogenmod 11)
This was tested on Nexus 6 with rooted Android 6 Stock ROM. This is heavily based on this Stackoverflow answer.
First, it is required to know the package name of the application. A list of all packages installed gives
pm list packages
It is important that the package name is <=26 characters long because "wrap.$PACKAGENAME" mustn't be longer than 31 characters (this is a limitation of the Android system, not of Valgrind or any other of our tools).
Next, put the following start script to /data/local/start_valgrind.sh
:
#!/system/bin/sh
PACKAGE="foo.bar.baz"
# TracerGrind
VGPARAMS='--kernel-variant=android-gpu-adreno3xx --trace-children=yes --tool=tracergrind --filter=foo.so --vex-iropt-register-updates=allregs-at-mem-access --output=/sdcard/foo.trace'
export TMPDIR=/data/data/$PACKAGE
exec /data/local/Inst/bin/valgrind $VGPARAMS $*
Make sure the package name is correct. You may remove or modify the filter parameter to your needs. Also, make sure that the script is accessible and executable.
After that, tell Android to start the application with your custom valgrind script:
PACKAGE="foo.bar.baz"
setprop wrap.$PACKAGE "logwrapper /data/local/start_valgrind.sh"
After that, starting the app on the phone or via am
should result in Valgrind output in logcat. The trace can be found in /sdcard/foo.trace
and from there everything works as usual.
- If somethings crashing and your device is soft rebooting, try disabling SELinux via
setenforce 0
- Sometimes the first start of the app after setting the logwrapper does not happen through the logwrapper. Simply stop the app and try starting the app again.
- If valgrind has problems with writing to
/sdcard/
, make sure the application requires the permissionandroid.permission.WRITE_EXTERNAL_STORAGE
. On Android >=6, make sure the permission is also granted. If you're not sure, go to Settings -> Apps -> your_app -> Permissions and enable it from there. - Valgrind reports a lot of unhandled instructions and the collected trace contains invalid messages of type some_number when converting it with texttrace/sqlittetrace: Currently there's no solution for this, see issue #6
- Nothing's happening after starting the app: If you can't see anything from
start_valgrind.sh
in your logcat, it's very likely that your package name is either wrong instart_valgrind.sh
and/or your logwrapper. If there is output fromstart_valgrind.sh
, look for error messages and file a new issue.
Investigate unhandled instruction errors from issue #6