Vallgrind and Android working together

Introduction

Valgrind has severall tools that can be used to identify and profile native applications, such as memcheck, callgrind, etc… This document will cover the settings for memcheck only.

This document is intended to be used with native Android applications.

Installation

Get sources from web from http://valgrind.org

Get Android ndk

configure environment as bellow

inside /etc/profile


 

JDK_HOME=/opt/java/jdk1.7.0_45/

RESOURCES_FOLDER=~/RESOURCES/

ANDROID_HOME=$RESOURCES_FOLDER/android-sdk/

GRADLE_HOME=$RESOURCES_FOLDER//gradle-2.0/

NDKROOT=$RESOURCES_FOLDER//android-ndk-r10

NDK_HOME=$NDKROOT

HWKIND=generic

TOOLCHAIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi

AR=$TOOLCHAIN-ar

LD=$TOOLCHAIN-ld

CC=$TOOLCHAIN-gcc

PATH=$PATH:$ANDROID_HOME/platform-tools

PATH=$PATH:$ANDROID_HOME/tools

PATH=$PATH:$GRADLE_HOME/bin:$JDK_HOME/bin:$NDK_HOME


 

Make and make install ;

 

On rooted device

create folder tree

/data/local/Inst

/data/local/Inst/tmp

 

copy valgrind binaries to device

adb push valgrind/Inst/data/local/Inst /data/local/Inst

chmod -R 777 data/local/Inst

 

Note: make sure the device has a good processor (to be faster) and have enough memory space, because valgrind binaries will occupy around 250 Mb of storage. Also have in mind that this only works on rooted or debug versions of android systems.

 

Deploy valgrind into android

Because one will deploy the android application on a remote target then two scripts will be required to bootstrap and run the app.

 

A bootstrap file bootstrap_valgrind.sh that must be on the host machine.


 

#!/usr/bin/env bash

PACKAGE=”COM.MY.PACKAGENAME

adb push suppresions.supp /data/local/Inst/suppresions.supp

adb push start_valgrind.sh /data/local/Inst/

adb shell chmod 777 /data/local/Inst/start_valgrind.sh

adb root

adb shell setprop wrap.$PACKAGE “logwrapper /data/local/Inst/start_valgrind.sh”

echo “wrap.$PACKAGE: $(adb shell getprop wrap.$PACKAGE)”

#The .StartActivity is the start activity of the Application

adb shell am force-stop $PACKAGE

adb shell am start -a android.intent.action.MAIN -n $PACKAGE/.StartActivity

# celar logcat

adb logcat -c

# start logcat

adb logcat

exit 0


 

The start file start_valgrind.sh that must be on the remote device, on the /data/local/Inst folder


 

#!/system/bin/sh

PACKAGE=”COM.MY.PACKAGENAME

# Callgrind tool

#VGPARAMS=’-v –error-limit=no –trace-children=yes –log-file=/sdcard/valgrind.log.%p –tool=callgrind –callgrind-out-file=/sdcard/callgrind.out.%p –vgdb=yes’

#VGPARAMS=’-v –log-file=/sdcard/valgrind.log.%p –tool=massif –massif-out-file=/sdcard/massif.out.%p ‘

#VGPARAMS=’-v –instr-atstart=no –error-limit=no –trace-children=yes –log-file=/sdcard/valgrind.log.%p –tool=callgrind –callgrind-out-file=/sdcard/callgrind.out.%p ‘

#export USER=root

#export HOSTNAME=t0lte

# Memcheck tool

VGPARAMS=’-v –log-file=/sdcard/valgrind.log.%p –leak-check=yes –leak-resolution=high –show-reachable=yes –error-limit=no –undef-value-errors=no –read-var-info=yes’

export TMPDIR=/data/local/Inst/tmp

echo “============Starting Valgrind ==============”

echo “Executing through valgrind: $VGPARAMS $*”

exec /data/local/Inst/bin/valgrind $VGPARAMS $*

#PORT=1234

#echo “running Valgrind debuger on port $PORT”

#exec /data/local/Inst/vgdb –port=$PORT


 

Notes: Package must not be bigger than 26 characters, because the setprop can have only 32 chars.

 

Compile Android project

On Android project, make sure to compile with debug flag without optimizations (thus it might work with optimizations also) and make sure the deployed APK has the debug symbols. Normally the libs folder have the .so files stripped that information, thus just copy them from the obj/local/armeabi to the folder libs/armeabi, and then deploy the APK to the device.

To verify if the .so files contains debug symbols :

arm-linux-androideabi-gcc-nm -a libs/armeabi/libsynclib.so

 

Start memory profiling

Now that we already have our project deployed into the android system, and the valgrind scripts are ready, just run the bootstrap_valgrind.sh script to start the profiling.

./bootstrap_valgrind.sh

 

Note that when using this profiling the app will become very slow (10 – 100 times slower), so just be patient

 

Retrieving results

After running the application on profile mode, make sure that one does actions that use the libs that should be analyzed and then retrieve the results that should be on the /sdcard/valgrind.log.%p, being that the last number is the PID of the process.

Just retrieve the files with

adb pull /scard/valgrind.log.%p

 

and then analyze them.

 

Analyzing memcheck output files

==PID== Invalid read of size 1

==PID== at 0x4832F54: strlen (vg_replace_strmem.c:415)

==PID== by 0x2EE6681F: Sender::BuildReplaceCommand(…) (Sender.cpp:624)

==PID== by 0x2EFC7DCB: Java_com_my_packagename_Classname_sync (jnibridge.c:130)

==PID== by 0x4F54B73: dvmPlatformInvoke (in /system/lib/libdvm.so)

==PID== Address 0x2d8bd1c1 is 0 bytes after a block of size 7,825 alloc’d

==PID== at 0x48315B8: calloc (vg_replace_malloc.c:626)

==PID== by 0x2EE667F7: Sender::BuildReplaceCommand(…) (Sender.cpp:621)

==PID== by 0x2EFC7DCB: Java_com_my_packagename_Classname_sync (jnibridge.c:130)

==PID== by 0x4F54B73: dvmPlatformInvoke (in /system/lib/libdvm.so)

 

For instance on the example above there’s a read of one byte (char) on a place that it shouldn’t with unexpected data.

 

Another examples … ask Google 🙂

 

Android Development: Sensors test

Using Eclipse IDE, Android Emulator, and SensorSimulator is possible to create android applications and simulating it without the need to install it on the physical device. This SensorSimulator is very useful because you can simulate a movement of the device and all the sensor data will be available to your application.

A few hiccups i encountered:
1º allow the Internet permission on the manifest file
2º remove the SDK target version requirement

</pre>
<code></code>

The installation and configuration of the sensorSimulator here!


private SensorManagerSimulator mSensorManager ;
public void onCreate()
{
...
mSensorManager = SensorManagerSimulator.getSystemService(this, SENSOR_SERVICE);
mSensorManager.connectSimulator();
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(listener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
}
@Override
protected void onStop() {
mSensorManager.unregisterListener(listener);
super.onStop();
}

private SensorEventListener listener = new SensorEventListener()
{
  public void onSensorChanged(SensorEvent event) {
    //Do Stuff Here
 }
};
}