In Android 2.2 Google announced ndk-gdb script which ease the debugging on the device. Later it turns out that it is not capable of debugging any other thread than the main thread.
In Android 2.3 Google ships fixed setup so you are now finally able to debug multithread application.
In fact multithread debugging is possible at least from Android 1.5. But you have to set up the environment yourself. Due to permissions limitation it is only possible on rooted devices. But it is possible on emulator as emulator is always rooted!
Here is a small shell script which does everything for you. It will start gdbserver on the device, gdb on PC and connect them together. It will also set up paths correctly so gdb can find its unstripped libraries on PC while having stripped libraries on the device.
Run this script from your project root directory. You have to modify APP_PACKAGE and ANDROID_TARGET variables to match your project settings. You also need to have you project compiled in debug mode. This can be done by running ndk-build NDK_DEBUG=1 or by setting android:debuggable=”true” in AndroidManifest.xml and compiling normally.
#!/bin/bash # Martin Hejna (c) 2011 # martin.hejna@gmail.com # CC-by ## Comment out for quiet run set -x # Set those variables to match your application [ "$APP_PACKAGE" ] || APP_PACKAGE="com.example" [ "$ANDROID_TARGET" ] || ANDROID_TARGET="android-9" # Set installation paths of SDK and NDK [ "$ANDROID_SDK" ] || ANDROID_SDK="/home/martin/Android/android-sdk-linux_86" [ "$ANDROID_NDK" ] || ANDROID_NDK="/home/martin/Android/android-ndk-r5" # adb and gdb executable paths ADB="$ANDROID_SDK"/platform-tools/adb GDB=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb # Check we are in application root path (the one with AndroidManifest.xml in it) APP_ROOT=`dirname $0` if [ ! -f $APP_ROOT/AndroidManifest.xml ] then echo This script must be run from package root directory echo This is the directory with AndroidManifest.xml in it exit 1 fi # Path to unstripped versions of native .so libraries UNSTRIPPED_SO_LIB="$APP_ROOT/obj/local/armeabi" APP_PROCESS=$UNSTRIPPED_SO_LIB/app_process APP_LIBC_SO=$UNSTRIPPED_SO_LIB/libc.so if [ ! -d $UNSTRIPPED_SO_LIB ]; then echo Error: Directory $UNSTRIPPED_SO_LIB does not exist exit 1 fi # Use cgdb if available if which cgdb > /dev/null then GDB_CMD="cgdb -d $GDB --" else GDB_CMD=$GDB fi # We use same port number on pc and on device DEBUG_PORT=5039 # File with gdb setup instructions (executed when gdb starts) [ "$GDB_SETUP" ] || GDB_SETUP="/tmp/gdb.setup" # Generate setup file for gdb with appropriate paths to symbols function gdb_setup() { cat <<EOF >$GDB_SETUP set solib-search-path $UNSTRIPPED_SO_LIB:$ANDROID_NDK/platforms/$ANDROID_TARGET/arch-arm/usr/lib directory $ANDROID_NDK/platforms/$ANDROID_TARGET/arch-arm/usr/include $APP_ROOT/jni $ANDROID_NDK/sources/cxx-stl/system ## set solib-absolute-prefix $ANDROID_NDK/platforms/$ANDROID_TARGET/arch-arm/usr/lib file $APP_PROCESS target remote :$DEBUG_PORT # Probably not needed. Uncomment if you have problems with watchdogs ## set variable gDvm.nativeDebuggerActive=true EOF } # Get pid of the process (first one if there are more of them) function get_pid_on_device() { $ADB shell ps | grep "$@" | awk '{print $2; exit}' } ############################################################################# ## Main entry ############################################################################ # Restart adb server. Uncomment if you have problems with adb being stuck ## $ADB kill-server # Get the app_process and libc.so from the device # Always download and overwrite those files to be sure we have correct ones $ADB pull /system/bin/app_process $APP_PROCESS $ADB pull /system/lib/libc.so $APP_LIBC_SO # Set up port forwarding for gdb and gdbserver if $ADB forward tcp:$DEBUG_PORT tcp:$DEBUG_PORT then : else echo Failed to setup tcp forwarding for port $DEBUG_PORT echo Is the device running? exit 1 fi # Get pid of the process APP_PID=`get_pid_on_device "$APP_PACKAGE"` if [ -z $APP_PID ] then echo "$APP_PACKAGE is not running" exit 1 fi # Kill any prior gdbserver GDBSERV_PID=`get_pid_on_device gdbserver` if [ -n "$GDBSERV_PID" ] then $ADB shell kill $GDBSERV_PID sleep 1 fi # Start gdbserver and attach it to our application $ADB shell gdbserver :$DEBUG_PORT --attach $APP_PID & sleep 2 # Invoke gdb and feed it with setup commands to set up path to libraries gdb_setup $GDB_CMD -x $GDB_SETUP rm -f $GDB_SETUP
Have fun!
I’m now assured that i need to root my device. Thanks a lot for the remarkable suggestions
I am currently self-assured that i should root my cell phone. Thanks a lot for the fantastic tips
Does this work if I connect gdb from Eclipse? I used your previous post to connect gdb with Eclipse. It works on emulator but not on real device. Also, does this command script works on Windows? Maybe if I run it from Cygwin?
It is remarkable, very useful phrase
Pavier Simpson
I about it still heard nothing