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.
Posted by Peter Teoh on April 23, 2013 at 11:34 pm
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).
Posted by Paul Aspradakis on May 25, 2014 at 10:10 am
What exactly is the directory ( /tmp/debuggerd ) you’re passing to the gdb client ?
Posted by Peter Teoh on May 25, 2014 at 10:35 am
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.
Posted by Paul Aspradakis on May 25, 2014 at 12:19 pm
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 ?
Posted by Peter Teoh on May 25, 2014 at 8:38 pm
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”.
Posted by Garrett Mcbrier on March 20, 2015 at 4:19 am
I get a Cannot attach to lwp XXXX: Operation not permitted. Can you help?
Posted by Peter Teoh on April 28, 2015 at 1:28 pm
this looked more like permission problem: the “gdbserver” command must be running as root to be able to attach to any process.