GDB graphical interface for GNU Emacs
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

GDB Graphical Interface for GNU Emacs

This package provides a graphical interface to the GDB debugger. It is intended to be fast and intuitive.


It was made as a drop-in replacement for the builtin package gdb-mi (check this question for the reason behind rewriting the entire package from scratch).


Instead of parsing the GDB/MI output in Elisp, I’ve created a dynamic module in C, which makes it run fast like a bullet!
Easy to use
The keybindings, which were inspired by Visual Studio and Qt Creator, were chosen to be easy to memorize and to provide the best interaction possible without much putting much strain on your fingers.
Does what you meant
Each command tries its best to infer what you meant when you run them.
You can change which buffer is displayed in each window, and even pop buffers to their own separate frames!
Simultaneous sessions
You can debug multiple programs at the same time, with different GDB sessions; each session creates its own frame.
Debug remotely
You may debug programs remotely over TRAMP!

List of special buffers

  • Threads
  • Stack frames
  • Breakpoints
  • Automatic variables
  • Watchers
  • Registers
  • Disassembly (of the selected stack frame)
  • Inferior I/O
  • GDB command shell (please read this question before going crazy!)

Interested? Here’s the quick-start guide!


  • GCC or Clang to compile the dynamic module
    • The module is automatically compiled as soon as possible
  • GDB (surprise, surprise) is needed to debug programs; I’ve only tested version 8.2, but will probably work on older ones
  • Emacs package Hydra is needed for the buffer switcher

Package installation

This package intentionally uses the name gdb-mi in order to shadow the builtin package, as it could be confusing to have two packages with the same purpose installed.

The easiest way to install it is by using Quelpa, which builds the packages for you from any source you want.

In order to install, give Quelpa the following package recipe:

'(gdb-mi :fetcher git
         :url ""
         :files ("*.el" "*.c" "*.h" "Makefile"))

It is highly recommended that you delete the autoloaded definitions from the builtin package in order to prevent confusion:

(fmakunbound 'gdb)
(fmakunbound 'gdb-enable-debug)

Here is an example configuration using use-package:

(use-package gdb-mi :quelpa (gdb-mi :fetcher git
                                    :url ""
                                    :files ("*.el" "*.c" "*.h" "Makefile"))
  (fmakunbound 'gdb)
  (fmakunbound 'gdb-enable-debug))

You may also do everything manually or use another package manager that supports Git repos. Example for straight.el:

(use-package gdb-mi
  :straight (:host github :repo "weirdNox/emacs-gdb" :files ("*.el" "*.c" "*.h" "Makefile"))
  (fmakunbound 'gdb)
  (fmakunbound 'gdb-enable-debug))

Smash those bugs!

After the installation is complete, you may start a debugging session.

If you want to debug an executable, run gdb-executable. You may also use this command to change the executable being debugged.

If you want another type of target, you may try running gdb-create-session and then inserting the commands manually in the shell buffer. I’ve not tested this, so I don’t know how well it works.

Default keybindings

The main way to interact with this package is by using the global minor mode gdb-keys-mode, which enables the usual keybindings you expect in a debugger, inspired by Visual Studio and Qt Creator:

F5 Run or continue
C-F5 (Re)Start and break at main
S-F5 Kill inferior
F6 Stop
F8 Create watcher
C-F8 Evaluate expression once
F9 Create or delete breakpoint
F10 Step over (instruction wise with M-)
C-F10 Run until cursor
F11 Step into (instruction wise with M-)
C-F11 Advance to cursor
S-F11 Step out
F12 Switch buffer or pop to frame

Nevertheless, even without the global minor mode, every buffer has some keybindings associated with it:

Threads buffer

SPC Select thread
c Continue thread
s Stop thread

Stack frames buffer

SPC Select frame
c Continue thread

Breakpoints buffer

d or or DEL Delete breakpoint
SPC Enable/disable breakpoint

Automatic variables buffer

SPC Create watcher (prompt with Shift )
RET Create watcher and select window (prompt with Shift )

Watchers buffer

a Add new expression
RET Assign to expression
e Edit expression under cursor
f Change format
d Duplicate
h Toggle frame holding
t Toggle access specifiers
SPC or TAB Toggle children
or DEL Delete watcher

Registers buffer

f Change format
SPC Create watcher (prompt with Shift )
RET Create watcher and select window (prompt with Shift )

Disassembly buffer

f Change format
F Change flavor


Why rewrite the already existing package that comes with Emacs?

There are many things that led to my decision of rewriting gdb-mi:
  • When I wanted to use it, I ended up having to modify and rewrite many functions in order to have predictable functionality
  • In some cases, the parsing would be so slow that I could not use it at all (when disassembling a big function and then stepping, for example)
  • It felt weird that it changed all my windows instead of opening in a new frame
  • Other reasons I’ve forgotten
  • I like C, Elisp, and a good challenge: I couldn’t find a package that used dynamic modules and it seemed like the perfect chance to do something I would use, as I couldn’t find a debugger for Linux that I could say I liked.

Why use this interface instead of [insert Linux graphical debugger here]?

Well, if you use Emacs, both this and the builtin package are great because you never need to leave the environment you use the rest of the day.

If you don’t use Emacs (but are willing to try it) and you can’t find a good graphical debugger for Linux, this could be it!

If you are already happy with what you have, then there isn’t much to see here. ☺

May I send custom GDB commands?

You may send any GDB command you want.

However, keep in mind that if:

  • the command does not use the background form (eg. continue&), it will block GDB until it finishes what it is doing, so you won’t be able to interact with it! If you want to interrupt it, run comint-interrupt-subjob in the command shell buffer (bound to C-c C-c ).
  • the command does not cause GDB to notify the interface of the changes it made, the interface may become out of sync and start giving errors

Other information