I am trying to remotely debug a pure C program on an Android device.
The Android device (target) is connected via USB to a host machine.
What I did was:
Copied from the target the following files:
/system/lib, /vendor/lib, /system/bin/app_process, and /system/bin/linker.
Target:
Copied gdbserver from NDK to the target device
Sent the exe that I want to debug
runned gdb server on target using ./gdbserver :5039 exec
this basically executes the process, and gets a pid
Host:
enabled the port adb forward tcp:5039 tcp:5039
runned: arm-eabi-gcc exec.
Then in gdb:
set solib-search-path ..., with the libraries that I pulled earlier from the target
target remote :5039
The arm-eabi-gcc can connect to the remote process, and even continue(c) the execution. However, I cannot set breakpoints. If I do, I get the following error:
Cannot access memory at address xxx.
Am I missing something here?
Thank you.
So, at host, in gdb shell, before specifying the remote's target port, I should type shared. This command loads the shared symbols.
Also, for compiling, I used -ggdb.
Related
I have a native C++ app which is supposed to run on an Android device. The application crashes at the startup, most likely when calling a function from a linked library. I am trying to debug it with gdb, but I can't succeed.
I am starting gdbserver on the Android device on some arbitrarily picked port (2000):
shell#msm8996: gdbserver :2000 my_app
Process my_app created; pid = 3420
Listening on port 2000
Now I am trying to attach to this process on my Host system (Windows 7) with gdb that was provided in Android-NDK.
C:\> gdb
(gdb) attach 3420
Can't attach to process.
(gdb) target remote :2000
:2000: The system tried to join a drive to a directory on a joined drive.
What is the problem?
EDIT:
Prior to running gdb I forwarded the port 2000 using adb:
adb forward tcp:2000 tcp:2000
This at least helped me to establish some communication, but:
(gdb) target remote :2000
Remote debugging using :2000
warning: Architecture rejected target-supplied description
Remote 'g' packet reply is too long: 00000000000000000000000000000...
On the device side:
Listening on port 2000
Remote debugging from host 127.0.0.1
readchar: Got EOF
Remote side has terminated connection. GDBserver will reopen the connection.
Listening on port 2000
You are most probably using different architecture / version of gdb. When you start the gdb, it displays a line like (I am showing what my GDB shows):
This GDB was configured as "--host=x86_64-linux-gnu
--target=arm-Linux-android"
Check if this matches with your phone's architecture.
Downloading the correct GDB version may solve your problem.
I have an android application that consists of a Java based APK, native executable, and native library. The apk talks to the native (root NDK c/c++) executable and library over a socket.
I'm not sure if it matters but the executable and library are compiled via cmake, and copied to be executable and then run as root. I need to get some type of debugging going with breakpoints and such, regardless of if it's directly in android studio or via command line.
You would need to run gdbserver on the device and let it attach to your executable
gdbserver comes prebuilt with ndk, usually under <ndk>/prebuilt/android-arm/gdbserver/
Copy gdbserver binary to your device, for instance to /data/local/tmp and give it executable permissions with chmod
If your executable is already running, find its PID with ps command and attach gdb to it:
gdbserver :5039 --attach <PID>
Note that 5039 is port number that is usually used for debugging with gdb, you can use your own if you like
set up a port forwarding from device to pc with
adb forward tcp:5039 tcp:5039
Run gdb locally, note that you need arm targeted gdb that comes with ndk too, usually at
<ndk>toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gdb
Attach gdb to your process
target remote :5039
And from here you need to use gdb commands that match your debugging expectations (set breakpoints, load symbols, step through etc), for examples use cheatsheet or ask in comments
I try to attach a process on my rooted Android and create corefile with GDB but it can't create a gcore file because the symbols could not be found.
on my phone, i open Terminal app and i input
su
to grant root access in Terminal. i input
dumpsys meminfo
to show all running processes. i input
gdbserver :1234 --attach 5132
on my computer, i open gdb.exe (from Android NDK) and i input
(gdb) target remote 192.168.1.13:1234
and i got those infomation
(gdb) target remote 192.168.1.13:1234
Remote debugging using 192.168.1.13:1234
warning: Architecture rejected target-supplied description
Reading /system/bin/app_process32_original from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
warning: A handler for the OS ABI "Cygwin" is not built into this configuration
of GDB. Attempting to continue with the default arm settings.
Reading /system/bin/app_process32_original from remote target...
warning: A handler for the OS ABI "Cygwin" is not built into this configuration
of GDB. Attempting to continue with the default arm settings.
Reading symbols from target:/system/bin/app_process32_original...(no debugging symbols found)...done.
0xb6e8b0f8 in ?? ()
With my own compiled gdb.exe, i got another info
(gdb) target remote 192.168.1.13:1234
Remote debugging using 192.168.1.13:1234
warning: Can not parse XML target description; XML support was disabled at compile time
Reading /system/bin/app_process32_original from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /system/bin/app_process32_original from remote target...
Reading symbols from target:/system/bin/app_process32_original...(no debugging symbols found)...done.
Remote 'g' packet reply is too long: fcffffff605fd9be10000000ffffffff0000000008000000000000005a010000a87687b414000000000000004010c032105fd9be005fd9be1352e6b6f8b0e8b610000f204a280000000000003d0000001100000000000000000000006000000004000000d002000068010000680100003702000052000010110000001600000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a28000072002e0073006500720076006900630065002e0056006f006900700043006f006e006e006500630074006f0072005300e83bb770e83bb77088639b70e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb770e83bb77011000060
0xb6e8b0f8 in ?? ()
i type
gcore
and it says
Can't create a corefile
I have installed the correct gdbserver binary that match with my kernel architecture in /system/bin
I tried different Android OSes below Android 4.4.4 which does not have PIE protection thing, but i still getting the same problem. I tried to use ported version gdb client and it works perfectly.
I just wanna save the corefile with my powerful device running Android 5.1.1 with 2 GB RAM, instead using gdb client on my low-end tablet that has 512 MB RAM and running Android 4.4.4, and the gdb could not fully create the corefile due to low RAM.
Just download gdb source and compile with below steps:
1).Compile gdb with below command:
cd gdb-7.11/gdb
./configure --target=arm-linux-androideabi --with-python --prefix=$HOME/mybinaries/bin
make
make install
2).Compile gdbserver with below command:
cd gdb-7.11/gdb/gdbserver
CC=arm-linux-androideabi-gcc LDFLAGS="-fPIC -pie" ./configure --target=arm-linux-androideabi --host=arm-linux-androideabi --prefix=$HOME/mybinaries/bin
make
make install
When compiling the GDB, i must give the target --target arm-linux-androideabi instead --target arm-eabi and it works perfectly
I'm trying to debug a native built (NDK) executable test (+shared library) using adb shell, gdbserver on one side and the ndk's gdb on the other side.
I copied the executable and .so to the device and executed in adb shell:
$ gdbserver :5039 ./my_test my_args
Process ./my_test created; pid = 11131
Listening on port 5039
On the host I run gdb on the same my_test executable:
$ $NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb ./my_test
And put a breakpoint in main():
Reading symbols from /.../my_test...done.
(gdb) target remote :5039
Remote debugging using :5039
warning: Unable to find dynamic linker breakpoint function.
GDB will retry eventurally. Meanwhile, it is likely
that GDB is unable to debug shared library initializers
or resolve pending breakpoints after dlopen().
0xb6f71a60 in ?? ()
(gdb) b main
Cannot access memory at address 0x0
warning: (Internal error: pc 0xa468 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0xa468 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0xa468 in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0xa46c in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0xa468 in read in psymtab, but not in symtab.)
...
When hooked to eclipse as remote debug the 'next statement' jumps to different places in the code when I attempt to step-by-step the code. This is the same thing that I see when I do a series of 'next' command in gdb.
gdbserver version on the device is 7.6.
Any ideas?
Update:
After building gdb 7.6.2 and using it instead of the gdb 7.3.1-gg which comes with the NDK release I have (r9d 64-bit), those warning messages of Internal error are gone.
What's left is the lack of sync between the code and debugging. I built the code with NDK_DEBUG=1 and copied the executable and .so from .obj dir to the device, but still when I do 'step-by-step' debug from gdb+gdbserver the program flow as seen from gdb doesn't make any sense.
OK, the issue is resolved. Now the program flow as seen from gdb looks as expected.
These are the two things that were done and made it work:
Build a newer version of gdb. Instead of the 7.3.1 which came with the NDK release (version r9d), I downloaded and built gdb with --target=arm-linux-gnueabi and used it.
Previously I specified -g in APP_CPPFLAGS inside Application.mk. This time, I specified -ggdb -O0.
I have built a binary excutable from pure C++ code and it prompts time error when running on android device.
How can I debug the pure native code for android? It seems that the existing methods are not for pure native code.
Step 1: Put the gdbserver and your unstripped native binary executable (suppose it is named testexec) on the android emulator. E.g. you can put it under folder /data/data/test. And use chmod command to add permissions to them.
Step2: Start gdb debugger. And this step consists of following sub-steps:
Step 2.1: Start gdb debugger of the emulator by typing command on your host machine terminal:
adb shell /data/data/test/gdbserver 10.0.2.2:1234 /data/data/test/testexec
The emulator will then listen on port 1234.
Step 2.2: Connect the gdb debugger of the local machine with the gdbserver of the emulator:
telnet localhost 5554
It will prompt:
Android Console: type 'help' for a list of commands
OK
Then input:
redir add tcp:1234:1234
to enable data redirection and then type
exit
Step2.3: Start the gdb debugger of the local machine. Input:
arm-linux-androideabi-gdb.exe YOUR_ EXECUTABLE_PATH_ON_LOCAL_MACHINE\testexec
After that, input
target remote localhost:1234
to connect to the gdbserver.
Finally, enjoy your debugging!
Android supports the use of GDB. However, I should note that if by "pure C++" you mean that there is no Java at all in the application, this is technically not allowed (although you can definitely do it). See the NDK page.