Code Monkey home page Code Monkey logo

emacs-gdb's Introduction

GDB Graphical Interface for GNU Emacs

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

assets/screenshot.png

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).

Features

Fast
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.
Organized
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!

Dependencies

  • 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 "https://github.com/weirdNox/emacs-gdb.git"
         :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 "https://github.com/weirdNox/emacs-gdb.git"
                                    :files ("*.el" "*.c" "*.h" "Makefile"))
  :init
  (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"))
  :init
  (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:

KeybindingDescription
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

KeybindingDescription
SPC Select thread
c Continue thread
s Stop thread

Stack frames buffer

KeybindingDescription
SPC Select frame
c Continue thread

Breakpoints buffer

KeybindingDescription
d or or DEL Delete breakpoint
SPC Enable/disable breakpoint

Automatic variables buffer

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

Watchers buffer

KeybindingDescription
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

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

Disassembly buffer

KeybindingDescription
f Change format
F Change flavor

FAQ

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

  • This package uses the library GDBWIRE for parsing the GDB/MI output.
  • The original Emacs GDB interface was my main inspiration, so thanks Nick Roberts!

emacs-gdb's People

Contributors

dragoncraft89 avatar kevinboulain avatar weirdnox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emacs-gdb's Issues

Terminal support?

Hi there,

From the screenshot it seemed promising but it looks like it makes use of GUI-only features.

I tried to comment out (define-fringe-bitmap 'gdb--fringe-breakpoint "\x3c\x7e\xff\xff\xff\xff\x7e\x3c") because define-fringe-bitmap isn't available and I could at least start an executable.
However, there are some rendering artifacts (in the asciinema below I have to either move the cursor to redraw lines or do a C-l to redraw the whole screen toward the end).
There is also no GDB prompt so I'm thinking I'm probably doing something stupid or that there is no terminal support yet (as the readme says that the interface may become out of sync when sending commands directly).
I must admit I didn't investigate much more than that :)

Here is the asciinema: https://asciinema.org/a/WPp7DiWvNwmkwL6hCUgV0xN70

By the way, I used the following use-package/straight declaration in case you want to add it to the readme too:

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

Tested with Emacs 26.1.

Feel free to close the issue if you don't intend to support this use case.

Regards.

Detect if emacs version supports dynamic modules

When trying this out, I just stumbled across a minor problem, that my emacs version did not support dynamic modules. The default, when building emacs on Linux, is that dynamic modules are disabled, so I had to recompile emacs first. This could be checked, when using the module-file-suffix in the code of your library. This would other people probably save time, when trying to investigate, why it doesn't work on the first attempt.

Help getting regular gdb back

I installed and tried it but Im and new and can't get it to work.
But now I can't get regular gdb back
because I used the
fmakunbound 'gbd configuration.

any Idea how I can get gbd back to a normal state?

.gdbinit is ignored

It seems, that emacs-gdb starts gdb with the option -nx, which prevents the usage of .gdbinit. This should probably be configurable, as in my setup I need .gdbinit, so I currently have to explicitly source it.

Thanks a lot for this great new package! It seems extremely promising and I am happy to help to improve it where possible. There are still a few minor quirks in it, but it's great!

[questions] how to debug C++ in docker with emacs

I'm using doom emacs.
I try your "emacs-gdb" because from now, I don't find any solution to debug C++ in a docker with emacs.
I summarize all in this post :
doomemacs/doomemacs#6168

In package.el I'm adding:

(package! quelpa)

In config.el I'm adding:

(setq confirm-kill-emacs nil)

(quelpa '(gdb-mi :fetcher git
          :url "https://github.com/weirdNox/emacs-gdb.git"
          :files ("*.el" "*.c" "*.h" "Makefile"))

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

I need to keep gdb-enable-debug otherwise I can not have the command gdb-executable by doing gdb-enable-debug first.
Do you know if it is the good way to use it on doom emacs ?

If I build in the docker,

I can open a file in the docker and do gdb-executable to choose the executable in the docker.
And this is working well.
Strangely, I can not make it working with original gdb -i=mi.
Do you have an idea why it is working in a docker with your package and not with original one "gdb" in emacs ?

If I build outside the docker

I'm using gdb-create-session to be able to pass command in gdb shell.
And I use the command "file" to choose the executable.
And after this one to have the good path in the docker :
set substitute-path /path/local /path/container

From the github page it seems you have not tested with gdb-create-session.
But this is the only way I know to path the command "set substitute-path".
Do you know if this is possible to use "emacs-gdb" with build outside the docker ?

Can't get emacs-gdb to work with remote target

I have tried to run the emacs-gdb package with a remote target. As the documentation on this is rather scarce I tried three different approaches:

  • I passed a TRAMP filename to gdb-executable. In this case, it seems that emacs-gdb invokes gdb locally, which cannot work
  • I set gdb-executable-name to "ssh:/user@host:/usr/local/bin/gdb" and then invoked gdb-executable with a local path. This results in an error message 'Wrong type argument: gdb--buffer-info, nil'
  • I set gdb-executable-name the same as above and additionally invoke gdb-executable with a remote path. This results in the same error message, as in the previous attempt.

Could you please describe how to set up the package to be able to debug remotely?
I'm not sure, if this matters, but I am using Emacs 28.0.90 with native compilation enabled on a Linux machine. The remote machine is Linux as well.

Segmentation fault

Happens when I debug a program that asserts in a thread. I simply wanted to r (run) until it crashes then up until I get in user code to peek around. When I reach user code, a crash follows.
A dummy program with a pthread_create & assert doesn't trigger the crash so sorry for the lack of example program.

Emacs' trace (truncated for brevity):

Fatal error 11: Segmentation fault
Backtrace:
emacs[0x4abee7]
emacs[0x492ec7]
emacs[0x4aa74e]
emacs[0x4aa948]
emacs[0x4aa9c9]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x128e0)[0x7f8c517dc8e0]
.../emacs/straight/build/gdb-mi/gdb-module.so(+0x997b)[0x7f8c4da6397b]
emacs[0x530978]
...

And the culprit is:

addr2line -e .../emacs/straight/build/gdb-mi/gdb-module.so +0x997b
.../emacs/straight/build/gdb-mi/gdb-module.c:1011

In my copy of gdb-module.c, line 1011 is the switch on Output->kind (I patched it to display Output's address so on master it should be line 1010):

diff --git i/gdb-module.c w/gdb-module.c
index 2c66ffc..a202ac3 100644
--- i/gdb-module.c
+++ w/gdb-module.c
@@ -1007,6 +1007,7 @@ static emacs_value handleGdbMiOutput(emacs_env *Env, ptrdiff_t NumberOfArgs,

     char *PrintString = 0;
     for(mi_output *Output = ParserOutput; Output; Output = Output->next) {
+        dprintf(2, ">>> Output:%p\n", Output);
         switch(Output->kind) {
             case GDBWIRE_MI_OUTPUT_OOB: {
                 handleMiOobRecord(Env, Output->variant.oob_record, &PrintString);

Right before crashing Emacs I get:

...
>>> Output:0x4052fe0
>>> Output:0x2ff8530
>>> Output:0x30

So there is probably a NULL pointer used somewhere.

By the way, why not compile gdb-module.so with debug symbols? It could help bug reports by giving you the line of crash (I had to modify the Makefile and recompile).

I hope it's enough, if is isn't feel free to request more.

Access gud + see output from executable

First of all, I am really impressed on how the package seems to work pretty well.

There are two things that I would like to ask:

  1. When using gdb-many-windows I also get to see the output from the executable. is it possible to get such behaviour with your package?
  2. Is it possible to send instructions to gdb directly? Similarly to the gud buffer when using the default gdb in emacs?

Thanks a lot!

Emacs26 dependency

I'm using Emacs 25.3.2 on Ubuntu 18.04, trying to install emacs-gdb gives error: Package ‘emacs-26.1’ is unavailable. Is there any way I can install emacs-gdb without upgrading to Emacs26? Thanks!

How to use a specific gdb?

I'm working with embedded systems and for them I use a specific arm gdb, how can I change the gdb executable that is used in this package? I really liked what you did with this package, is awesome.

Error on gdb-executable

I tried to use emacs-gdb for the first time. The installation processed without any problems after adding the use-package-quelpa instructions of the README to my init.el. But when i try to run gdb-executable, emacs prints out the message:

error in process filter: ansi-color-process-output: Wrong type argument: processp, nil
error in process filter: Wrong type argument: processp, nil

Does someone got the same issue and solved it maybe?

Some input problems

A bunch of problems I encountered:

  • GDB thinks its input isn't from a terminal and will always confirm when it would have prompted the user otherwise (which may or may not be a good idea, this is a minor issue)
  • can't properly define functions nor use them (their output is probably interpreted?)
  • sometimes (rarely but happens) input get stuck (and pressing C-g will traceback, I got lucky and got this one recorded so sorry for record that could probably been have a bit better)

Here is an asciinema, it probably explains better than I can: https://asciinema.org/a/pqlKW2G8nHxDT2PV0xPewKvNQ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.