Can anyone tell me how to run ndk-gdb from within emacs using gdb-mode? I’m currently running it in a shell buffer. What I’d love to have is a way to automatically sync a source file buffer with the current pc in gdb when I break or step. Anything more, like setting breaks from source, buffers that show gdb locals etc., and key shortcuts for gdb commands would be gravy.
Background: I’m developing in GNU Emacs 18.104.22.168 (i386-apple-darwin10.5.0, NS apple-appkit-1038.35) of 2010-12-15 on OSX 10.6.6 with android-mode, using android-ndk-r5b and mixed java/c/c++ code for an android target.
Android-mode and shell (running ndk-gdb) within emacs allow me to see just about everything I need, but my setup would be more convenient if I could get a source buffer to sync with the debugger, or get the equivalent of what is described in EmacsWiki here.
FYI, I’m currently using eclipse for java side debugging and development, but finding it unstable and difficult to set up for native work, despite the availability of sequoyah, and besides, eclipse is no emacs.
Running M-x gdb with ndk-gdb as the gdb command (see below) results in a buffer called gud with a modeline saying “(Debugger:run [initializing…])”. The buffer does not accept gdb commands, nor does it accept emacs gdb commands – (M-s, M-n etc result in <>
Current directory is /Users/jpschelter/ Android NDK installation path: /Developer/android-ndk-r5b Using specific adb command: /Developer/android-sdk-mac_x86/platform-tools/adb ... ... ... ... (no debugging symbols found) warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. 0xafd0e21c in nanosleep () from /Developer/Projects/ECS/DIGG/Projects/droid/obj/local/armeabi/libc.so (gdb) Undefined command: "1-inferior-tty-set". Try "help". (gdb) Undefined command: "2-gdb-set". Try "help". (gdb) Undefined command: "3-gdb-set". Try "help". (gdb) Undefined command: "4-file-list-exec-source-files". Try "help". (gdb) Undefined command: "5-file-list-exec-source-file". Try "help". (gdb) Undefined command: "6-gdb-show". Try "help". (gdb) Undefined command: "7-stack-info-frame". Try "help". (gdb) Undefined command: "8-thread-info". Try "help". (gdb) Undefined command: "9-break-list". Try "help".
*input/output of* and
*breakpoints of* are also created, but are empty.
Browsing through the gdb-mi.el source of my emacs, and comparing to the gdb-debug-log output, it looks like gdb-mi is trying to send these parameters to a gdb executable, but gdb-server is not responding to the commands as expected?
Note that running M-x gud-gdb with the command-line for ndk-gdb seems to result in the equivalent of running ndk-gdb within a shell, so the issue seems to be within the configuration of gdb-mode in emacs.
I had the exact same problem when running gdb under emacs: the *gud* window was not responding to commands. However, ndk-gdb was working well in a shell. To make it work under the emacs gud UI, I had to modify the ndk-gdb script a bit.
On call to GDB (last line), do this:
$GDBCLIENT --annotate=3 -x `native_path $GDBSETUP`
The –annotate=3 option is mandatory for emacs gud interface, it cannot work without it (that’s why *gud* was not responding).
But you’re halfway. Now it will work, but only if you invoke ndk-gdb while in a buffer from a file at the root of the project (like AndroidManifest.xml). Since this is very unlikely most of the time because you are a C/C++ programmer and the sources you’re working on are under the jni directory or deeper, you need to do a little more. The ndk-gdb script is a bit buggy and it will happily confuse you on this one (and gdb itself won’t help much either).
Search the script for “PROJECT=$OPTION_PROJECT”. You will be in a long if…else…fi clause which is in charge of finding the root of the project (if it has not been given with the –project option, though doing so WILL NOT resolve the issue I talk about, see below). After the fi, add this line:
For some obscure reason, the script DOES NOT cd to the project root directory. This leads to very wrong behaviour when dealing with the gdb.setup file where the script assumes to be at project root. Adding this line will fix it.
Make sure you call ndk-gdb within emacs with the usual command:
(gdb "ndk-gdb ...")
Do not use gud-gdb (oddly, this is old emacs way of using gdb and has nothing to do with the nice UI you’re searching for). Replace … with your arguments, (concat …) or anything you wish. I strongly recommend to use the –project option anyway. If you don’t and you are in a buffer for a file which is out of the project, the script won’t find the root. Worse, if you’re in a file in another Android project, it will find the root of that project instead (maybe even copying gdb.setup and stuffs into it before failing the gdb session). So give that damn –project option. If you’re using emacs desktop command set, do this:
(gdb (concat "ndk-gdb --project=" desktop-dirname ...))
(assuming your .emacs.desktop is at the root of the project, of course).
Now you can finally debug with gud UI, setting breakpoints at source level.
Note that I use emacs 23.3.1 (gdb-ui.el), so there is no need to have 24 for this to work.
Have you tried this?
Add android-sdk-mac_x86/platform-tools and android-ndk-r5b to PATH environment. After that, start gdb mode with ndk-gdb script.
M-x gdb Run gdb (like this): ndk-gdb --verbose --start --project=your_NDK_project_dir