How to do remote debugging via gdbserver running inside the Android phone?

Presently, my phone is a Samsung Galaxy S3 GT-I9300. But in general the following steps should be applicable to any Android device.

First, download Android SDK and NDK. From SDK you can get the “adb” to connect into the phone. From NDK you can get the gdbserver in ARM binary, upload that to the phone via “adb”.

Next mount the /system as read-writeable (you need to be root first, ie, a rooted device is assumed):

mount -o rw,remount /dev/block/mmcblk0p9 /system

(the block device “/dev/block/mmcblk0p9” is specific to my device, yours may differ. Just use “mount” to see which block device the “/system” directory is mounted on. If “/system” does not appear in “mount” command, then most probably the root filesystem block device should be used.)

And then copy the gdbserver from the Android NDK into /system/bin directory.

Next, assuming the process ID of the target process is 16835, then run this inside the Android phone (MUST BE ISSUED AS “root” user again):

gdbserver :4567 --attach 16835
Attached; pid = 16835
Listening on port 4567

In another PC (which is accessible by TCP/IP from the phone, download all the ARM-based libraries from the phone and run the gdb client):

Get all the ARM libraries and the target binaries (to be debugged, and in my case, it is called “debuggerd”) from mobile phone:

adb pull /system/lib /tmp/system_lib

And run the gdb client (which is from the NDK) on the PC side (and remember to disable all firewall via “iptables -F” and “ip6tables -F” just in case they are interfering with the network transfer:

/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb /tmp/debuggerd
(gdb) set auto-solib-add on
(gdb) target remote 10.10.1.25:7892
(gdb) set solib-search-path /tmp/system_lib

Subsequent messages:

Error while mapping shared library sections:
/system/bin/linker: No such file or directory.
Symbol file not found for /system/bin/linker
Reading symbols from /tmp/system_lib/libc.so...(no debugging symbols found)...done.
Loaded symbols for /tmp/system_lib/libc.so
Reading symbols from /tmp/system_lib/libstdc++.so...(no debugging symbols found)...done.
Loaded symbols for /tmp/system_lib/libstdc++.so

As shown above, all the dynamic libraries files are read and recognized by the gdb client, except for “/system/bin/linker”.

(gdb) info sharedlibrary
From To Syms Read Shared Object Library
No /system/bin/linker
0x4015a0c0 0x401882d4 Yes /tmp/system_lib/libc.so
0x4019e934 0x4019ea3c Yes /tmp/system_lib/libstdc++.so
0x401a1f70 0x401b1db8 Yes /tmp/system_lib/libm.so
0x400332a0 0x4004441c Yes /tmp/system_lib/libz.so
0x400b1a00 0x401172b8 Yes /tmp/system_lib/libcrypto.so
0x4005f530 0x4007798c Yes /tmp/system_lib/libssl.so
(gdb)

After this you can issue “x /100i <addr>” to enumerate the instructions starting from <addr> running on the Android device, or “s” to single step through all the instructions. Just remember that the process is always 16835 as specified earlier.

Done.

Advertisements

7 responses to this post.

  1. For my Nexus 7, from inside the Nexus 7:

    cat /proc/mounts |grep system

    /dev/block/platform/sdhci-tegra.3/by-name/APP /system ext4 ro,relatime,user_xattr,acl,barrier=1,data=ordered 0 0

    Therefore to change it to read-writeable:

    mount -o rw,remount /dev/block/platform/sdhci-tegra.3/by-name/APP /system

    And inside the NDK’s prebuilt directory I found gdbserver under “android-arm” directory:

    /opt/android-ndk-r8c/prebuilt/android-arm/gdbserver

    copy that to /system/bin inside Nexus7.

    Next I used gdbserver to debug Adobe reader (another new article).

    Reply

  2. What exactly is the directory ( /tmp/debuggerd ) you’re passing to the gdb client ?

    Reply

  3. gdb client (which is usually x86) is running in Linux, and the gdbserver is running in the handphone (usually ARM). in the linux host, “gdb xxx” (where xxx is /tmp/debuggerd) is just ANY image file, but what is actually executing is the binary in the handphone. Preferably, it should be the same binary image as the one running inside the handphone….otherwise when you enter “break *0xabcd” or “break yyyy” the symbol “yyyy” or address “abcd” will have to be identical to that running by the gdbserver.

    In our case, gdbserver is attaching to pid 16835, which is the “debuggerd” process inside the handphone, and so I copy out the binary file and put it into the /tmp/ in the linux host, and do a “gdb /tmp/debuggerd”. hope u understand better gdbserver’s architecture now, which true and highly useful for embedded development.

    Reply

  4. Thanks for the reply, I am currently trying to figure out if it’s possible to find the location of the binary image of a certain application through its process id or maybe its shortcut.
    By the way do you have an e-mail address I can use to contact you or do you maybe hang around in any IRC channel ?

    Reply

    • sure, my email: htmldeveloper@gmail.com

      and btw, for your problem:

      ps give:

      tthtlc 2323 2316 0 17:36 pts/0 00:00:00 bash

      and pid=2323:

      and then u do “cat /proc/2323/maps” or “cat /proc/2323/smaps” or “cat /proc/2323/cmdline” etc….all of which u can see the directory of the binary….which is “/bin/bash”.

      Reply

  5. I get a Cannot attach to lwp XXXX: Operation not permitted. Can you help?

    Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: