https://www.linkedin.com/pulse/android-thread-annotations-simplified-sergio-lima
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.
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.
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.
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
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
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.
==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 🙂
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 } }; }