gdb-mi is a package by Nick Roberts which makes Emacs use GDB/MI interface to talk with the GNU Debugger.
gdb-mi is currently in Emacs trunk, replacing the old
gdb-ui package in GNU Emacs.
The goal of this project is to migrate the GDB graphical interface in Emacs to completely use GDB’s Machine Interface (GDB/MI). This will make GDB support in Emacs more robust and will allow using of GDB features available only with MI.
The development is carried out by Dmitry Dzhus under mentorship of Nick Roberts.
See this package stats at Ohloh!
This section provides an overview of new user-visible features implemented during Google Summer of Code. This draft serves as a base for updated section of the Emacs manual (see «GDB Graphical Interface»).
Note that the development version of GDB 7.0 is needed for this package to work (
-thread-info command, non-stop debugging support).
With MI, the notion of «current thread» is not so important as it provides means to query information for any thread without actually selecting it. This means that much more current thread selection logic may be implemented in the frontend without relying on the internal state of the debugger.
It’s now possible to observe information for several threads simultaneously (in addition to buffers which show information for currently selected thread). Select threads buffer by clicking «Threads» button or using
gdb-display-threads-buffer command. Now you can ask Emacs to show information for thread under point using these keybindings, either using the current frame or creating a new one:
C-h m in threads list buffer will also give you this list.)
When you create a buffer showing information about some specific thread, it becomes «bound» to that thread and keeps showing actual information while you debug your program.
Non-stop debugging is much less intrusive.
To activate non-stop mode, set
gdb-non-stop-setting customization variables to
t. Note that changing this while debugging a program has no effect.
By default, when a thread stops in non-stop mode, Emacs automatically switches to that thread.
It may be undesirable to let Emacs switch current thread when you already have some other stopped thread selected. Set
nil to prevent this.
Emacs can decide whether or not to switch to stopped thread depending on the reason which caused the stop. Customize
gdb-switch-reasons to select stop reasons which make Emacs switch thread.
gdb-stopped-hooks hook variable allows you to execute your functions whenever some thread stops. For example:
(defun my-gdb-stopped-hook (record) (with-current-buffer (get-buffer-create "*debug-stop-log*") (insert (format "%s stopped in %s (%s)\n" (gdb-get-field record 'thread-id) (gdb-get-field record 'frame 'func) (gdb-get-field record 'reason))))) (add-to-list 'gdb-stopped-hooks #'my-gdb-stopped-hook)
In non-stop mode, you can switch between different modes for GUD execution control commands.
t(that’s default), interruption & continuation commands apply to all threads, so you can halt or continue all your threads with one command (
gud-cont, respectively). Go button is shown on the toolbar when at least one thread is stopped, whereas Stop button is shown when at least one thread is running.
gdb-gud-control-all-threadsvalue means that only current thread is stopped/continued. Go/Stop buttons on the GUD toolbar are shown depending on the state of current thread.
Stepping commands always apply to current thread.
In non-stop mode, you can interrupt/continue your threads without selecting them. Hitting
i in threads list buffer interrupts thread under point,
c continues it,
s steps through. More commands may be added in the future.
Note that when you interrupt a thread, it stops with «Signal received» reason. If that reason is included in your
gdb-switch-reasons (it is by default), Emacs will switch to that thread.
Given that you can create bound buffers for any thread, this allows you to observe state of many threads in the same time.
See the annotated screenshot showing how Emacs works with non-stop GDB:
You can customize what fields are included in stack frames list and threads list by changing options in
gdb-buffers customization group.
The following has been done for
gdb-mi.el during Summer of Code 2009.
Implemented buffers for:
Internals (you don’t want to read this):
gdb-buf-publisherprovides a cleaner way to ask buffers to update; we maintain
gdb-threads-list; we’re still tied to «one buffer — one handler» model)
fadr.elis a bad idea
-symbol-info-symboland unimplemented MI commands.
-break-listcauses JSON parser to suffer fixed. RET behaviour in GUD buffer fixed. GDB
shellcommand and GUD buffer fixed. Killing GDB buffer does not send
No source file named .problem fixed.
No source file named .(second report). Shell aliases are ignored when running GDB under Emacs
gdb-mi.el sets all its windows to be dedicated by default which means that if one tries to switch-buffer in one of
gdb-mi.el’s dedicated windows the buffer will appear in a different window instead. This can be rather annoying, so here’s a quick fix using advice to override
gdb-mi.el’s window dedication.
;; Force gdb-mi to not dedicate any windows (advice-add 'gdb-display-buffer :around (lambda (orig-fun &rest r) (let ((window (apply orig-fun r))) (set-window-dedicated-p window nil) window))) (advice-add 'gdb-set-window-buffer :around (lambda (orig-fun name &optional ignore-dedicated window) (funcall orig-fun name ignore-dedicated window) (set-window-dedicated-p window nil)))