Android - Valgrind for applications

    This is just about running an android application with Valgrind. From my experience, it didn't help at all as the application is painfully slow and in some cases causes ANR. This is even more complicated as non-nexus devices based on Snapdragon has a patch to kill the process upon ANR instead of showing the ANR dialog. This is documented here.

   Anyways, here are the steps to enable Valgrind

1) Prerequisites : Ubuntu, Android ND, SVN, Rooted android device based on ARM

2) Download Valgrind source code

        svn co svn://svn.valgrind.org/valgrind/trunk valgrind

3) Set NDKROOT to Android NDK's path

       export NDKROOT=/home/user/android-ndk-r10d

4) Change directory into the downloaded valgrind source code and run a script,

       ./autogen.sh

5) Execute the following commands in the same directory to build and generate valgrind binary,

export HWKIND=generic

export AR=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar
export LD=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ld
export CC=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc

CPPFLAGS="--sysroot=$NDKROOT/platforms/android-14/arch-arm -DANDROID_HARDWARE_$HWKIND" \
CFLAGS="--sysroot=$NDKROOT/platforms/android-14/arch-arm" \
./configure --prefix=/data/local/Inst \
--host=armv7-unknown-linux --target=armv7-unknown-linux \
--with-tmpdir=/sdcard

make
make -j2 install DESTDIR=`pwd`/Inst

6) Push the newly generated Inst directory on to the android device. This would be stored in /data/local/Inst.

adb push Inst /

7) Change the execution permission

adb shell
#chmod -R 744 /data/local/Inst

8) Check the version to check Valgrind executable status,

adb shell 
#/data/local/Inst/bin/valgrind --version

9) Create a script file (start_valgrind.sh) on the host machine with the following contents. package_name has to be replaced with that of the desired application.

#!/system/bin/sh
VGPARAMS='--error-limit=no --trace-children=yes --tool=memcheck --sigill-diagnostics=no --'
export TMPDIR=/data/data/package_name
echo "Executing through valgrind: $VGPARAMS $*"
exec /data/local/Inst/bin/valgrind $VGPARAMS $*

10) Push the script on to the device and change its permission

adb push start_valgrind.sh /data/local/
adb shell chmod 744 /data/local/start_valgrind.sh

11) Set a property (package_name has to be replaced with that of the application).

adb shell setprop wrap.package_name "logwrapper /data/local/start_valgrind.sh"

12) Kill and restart the application via adb. LauncherActivity would be the name of the activity handling the launch intents from Launcher app.

adb shell am force-stop package_name
adb shell am start -a android.intent.action.MAIN -n package_name/.LauncherActivity

   And we have an application monitored via valgrind. Sadly, this is too slow. The only hope is for LeakSanitizer to be enabled on Android running on ARM64. This isn't ready as of now and is pending.


No comments: