The GNU Project debugger (GDB) is a commonly used Unix debugger. This page
gdb to debug Android apps and processes for platform
developers. For third-party app development, see
Debug Your App.
Debugging running apps or processes
To connect to an already-running app or native daemon, use
gdbclient.py with a PID. For example, to debug the process with PID
gdbclient.py -p 1234
The script sets up port forwarding, starts the appropriate
gdbserver on the device, starts the appropriate
the host, configures
gdb to find symbols, and connects
gdb to the remote
Debugging native process startup
To debug a process as it starts, use
gdbserver64. For a 64-bit executable:
adb shell gdbserver64 :5039 /system/bin/MY_TEST_64_BIT_APP
For a 32-bit executable:
adb shell gdbserver :5039 /system/bin/MY_TEST_32_BIT_APP
Process MY_TEST_64_BIT_APP created; pid = 3460 Listening on port 5039
Next, identify the application PID from the
gdbserver output and
use it in another terminal window:
gdbclient.py -p APP_PID
Finally, enter continue at the
Note: If you specify the wrong
gdbserver, you'll get an unhelpful error message (such as
Reply contains invalid hex digit 59").
Debugging app startup
Sometimes you want to debug an app as it starts, such as when there's a crash
and you want to step through code to see what happens before the crash.
Attaching works in some cases, but in other cases is
impossible because the app crashes before you can attach. The
logwrapper approach (used for
valgrind) does not always work because the app might not have
permissions to open a port, and
gdbserver inherits that
To debug app startup, use the developer options in Settings to instruct the app to wait for a Java debugger to attach:
- Go to Settings > Developer options > Select debug app and choose your app from the list, then press Wait for debugger.
- Start the app, either from the launcher or by using the command line to run:
am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
- Wait for the app to load and a dialog to appear telling you the app is waiting for a debugger.
gdbclientnormally, set breakpoints, then continue the process.
To let the app actually run, attach a Java Debug Wire Protocol (JDWP) debugger such as Java Debugger (jdb):
adb forward tcp:12345 jdwp:XXX # (Where XXX is the pid of the debugged process.)
jdb -attach localhost:12345
Debugging apps or processes that crash
If you want
debuggerd to suspend crashed processes so you can
gdb, set the appropriate property:
# Android 7.0 Nougat and later.
adb shell setprop debug.debuggerd.wait_for_gdb true
# Android 6.0 Marshmallow and earlier.
adb shell setprop debug.db.uid 999999
At the end of the usual crash output,
instructions on how to connect
gdb using the command:
gdbclient.py -p PID
Debugging without symbols
For 32-bit ARM, if you don’t have symbols,
gdb can get confused
about the instruction set it is disassembling (ARM or Thumb). To specify the
instruction set chosen as the default when symbol information is missing, set
the following property:
set arm fallback-mode arm # or thumb