page.title=ndk-gdb @jd:body
The NDK includes a helper shell script named {@code ndk-gdb} to easily launch a native debugging session for your NDK-generated machine code.
For native debugging to work, you must follow these requirements:
cd $PROJECT $NDK/ndk-gdb
Here, {@code $PROJECT} points to your project's root directory, and {@code $NDK} points to your NDK installation path.
When you invoke {@code ndk-gdb}, it configures the session to look for your source files and symbol/debug versions of your generated native libraries. On successfully attaching to your application process, {@code ndk-gdb} outputs a long series of error messages, noting that it cannot find various system libraries. This is normal, because your host machine does not contain symbol/debug versions of these libraries on your target device. You can safely ignore these messages.
Next, {@code ndk-gdb} displays a normal GDB prompt.
You interact with {@code ndk-gdb} in the same way as you would with GNU GDB. For example, you can use {@code b <location>} to set breakpoints, and {@code c} (for "continue") to resume execution. For a comprehensive list of commands, see the GDB manual.
Note that when you quit the GDB prompt, the application process that you're debugging stops. This behavior is a gdb limitation.
{@code ndk-gdb} handles many error conditions, and displays an informative error message if it finds a problem. these checks include making sure that the following conditions are satisfied:
By default, {@code ndk-gdb} searches for an already-running application process, and displays an error if it doesn't find one. You can, however, use the {@code --start} or {@code --launch=<name>} option to automatically start your activity before the debugging session. For more information, see Options.
To see a complete list of options, type {@code ndk-gdb --help} on the command line. Table 1 shows a number of the more commonly used ones, along with brief descriptions.
Option | Description> |
---|---|
{@code --verbose} | This option tells the build system to print verbose information about the native-debugging session setup. It is necessary only for debugging problems when the debugger can't connect to the app, and the error messages that {@code ndk-gdb} displays are not enough. |
{@code --force} | By default, {@code ndk-gdb} aborts if it finds that another native debugging session is already running on the same device. This option kills the other session, and replaces it with a new one. Note that this option does not kill the actual app being debugged, which you must kill separately. |
{@code --start} | When you start {@code ndk-gdb}, it tries by default to attach to an existing running instance of your app on the target device. You can override this default behavior by using {@code --start} to explicitly launch the application on the target device before the debugging session. |
{@code --launch=<name>} | This option is similar to {@code --start}, except that it allows you to start a specific activity from your application. This feature is only useful if your manifest defines multiple launchable activities. |
{@code --launch-list} | This convenience option prints the list of all launchable activity names found in your app manifest. {@code --start} uses the first activity name. |
{@code --project=<path>} | This option specifies the app project directory. It is useful if you want to launch the script without first having to change to the project directory. |
{@code --port=<port>} | By default, {@code ndk-gdb} uses local TCP port 5039 to communicate with the app it is debugging on the target device. Using a different port allows you to natively debug programs running on different devices or emulators connected to the same host machine. |
{@code --adb=<file>} | This option specifies the adb tool executable. It is only necessary if you have not set your path to include that executable. |
|
These flags are similar to the adb commands with the same names. Set these flags if you have several devices or emulators connected to your host machine. Their meanings are as follows:
Alternatively, you can define the {@code ADB_SERIAL} environment variable to list a specific device, without the need for a specific option. |
|
This option tells {@code ndk-gdb} to run the GDB initialization commands found in {@code <file>} after connecting to the process it is debugging. This is a useful feature if you want to do something repeatedly, such as setting up a list of breakpoints, and then resuming execution automatically. |
{@code --nowait} | Disable pausing the Java code until GDB connects. Passing this option may cause the debugger to miss early breakpoints. |
{@code --tui} {@code -t} | Enable Text User Interface if it is available. |
{@code --gnumake-flag=<flag>} | This option is an extra flag (or flags) to pass to the {@code ndk-build} system when querying it for project information. You can use multiple instances of this option in the same command. |
{@code --stdcxx-py-pr={auto|none|gnustdcxx[-GCCVER]|stlport}} | Use specified Python pretty-printers for displaying types in the Standard C++ Library. {@code auto} mode works by looking at the {@code .so} files for a {@code libstdc++} library, and as such only works for a shared library. When linking statically to a {@code libstdc++} library, you must specify the required printers. The default is {@code none}. |
Note: The final three options in this table are only for the Python version of {@code ndk-gdb}.
If your app runs on a platform older than Android 2.3 (API level 9), {@code ndk-gdb} cannot debug native threads properly. The debugger can only debug the main thread, abd completely ignores the execution of other threads.
Using a version of Android prior to 2.3 causes {@code ndk-gdb} to display the following message prior to showing the GDB prompt:
Thread debugging is unsupported on this Android platform!
If you place a breakpoint on a function executed on a non-main thread, the program exits, and GDB displays the following message:
Program terminated with signal SIGTRAP, Trace/breakpoint trap. The program no longer exists.