Skip to content
strangepr0gram edited this page Sep 7, 2022 · 38 revisions
Table of Contents

See also the notes for specific buffers:

Loading and Unloading

To load the package:

  M-x load-library realgud

To unload the package

  M-x realgud-unload-features

And, of course, to reload do an unload followed by a load.

See Debuggers Available for a list of debuggers that are supported.

When there is no conflict with command from another package like gud, there are function aliases to the names without realgud:. For example:

M-x trepan2

is the same as

M-x realgud:trepan2

This means gud, perldb, pdb, and jdb (among possibly others) need to have the realgud: prefix if you want the realgud to run these.

You can also attach a debugger tracking mode to an existing comint shell. Inside a shell buffer:

M-x realgud-track-mode

You will be asked for the name of a buffer. Use one of the names above without realgud-. For example, trepan.

Some debuggers have the ability to call the debugger from inside a running program rather than at the outset. In those debuggers, there is often an alternate command you can run which appends -delayed after the debugger-name. Specifically:

M-x trepan2-delayed

works like trepan2 but the program is run from the outset via invoking Python and it will stop only after the debugger is called from the with program such as via from trepan.api import debug; debug().

For gdb, in order to track source automatically, inside gdb issue:

set annotate 1

The debugger saves marks in a history ring at the places in source buffers that you have stopped at. To move around M-up and M-down in the debugger command buffer. (The command buffer is where you enter debugger commands which is attached to the debugger process. It is some sort of comint shell.

There is a "short-key" mode which can be used in source buffers which allows single-keystroke commands, like "s" for step (into). And "n" for "next" or step through.

The short-key mode makes the source read only. To get out of short-key mode, you can use the insert key, or Ctrl-x Ctrl-q (command realgud-short-key-mode). To get back in use Ctrl-x Ctrl-q or run something in the command buffer that causes a position to be shown, like up 0 for gdb-like debuggers.

If you're having key mapping conflicts with other mode (e.g. evil-mode), you can assign a prefix to the same key shortcuts by adding the following hook:

(add-hook 'realgud-short-key-mode-hook
        (lambda ()
          (local-set-key "\C-c" realgud:shortkey-mode-map)))

The field src-shortkey? of the structure realgud-cmdbf-info which is a buffer local varabile in the command buffer indicates whether source buffers should go into short-key mode.

Multiple files

You may want to launch the debugger against one file (e.g. main.py) and use short-key mode on other files (e.g. if main.py uses a function defined in a module that you want to debug). You need to attach each file where you want to use short-key mode to the debugger command buffer. You can do so with the shortcut C-x C-a C-q. It will prompt you to choose one that it's running. Once you enter it, you are all set.

The editor uses marks in the source buffer. However if you edit the program and then restart the debugger you may need to clear these marks with

M-x loc-changes-clear-buffer

When you run a debugger from a top-level realgud command, such as M-x remake, realgud needs a command buffer which is a kind of process buffer. realgud uses this process buffer to communicate commands to and get output from the debugger. For example if I run M-x remake I may be prompted

remake --debugger -f Makefile

and if I accept this the name of the buffer is called `remake Makefile shell.

The name of command buffer is based on the invocation. The buffer name starts and ends with * which indicates some sort of temporary buffer, or buffer with no external file path associated with it. The buffer name also ends in shell* since this process buffer is also derived off of shell-mode. The name after the leading *is the debugger name, hereremake, and the next word is the name of the thing being debugged, or Makefile`.

The first two lines of that buffer have some debugger process information.

Continuing with the example above, the *remake Makefile shell* will contain initially:

Current directory: /tmp/remake/doc/
Command: remake --debugger -f Makefile
Reading makefiles...
Updating makefiles...
-> (/tmp/remake/doc/Makefile:900)
Makefile: Makefile.in ../config.status
remake<0>

The first line in the buffer is the current working directory. Where does that come from? It is simply the current working directory for what buffer you were in when you invoked the remake command inside GNU Emacs.

If you invoke the debugger command, e.g. remake from inside the thing you want debugged, generally this will be the right current directory. Likewise if you invoke this from a shell buffer and set the shell buffer to the rook of where you want to start, again the correct current directory will be set.

Some programs like remake however have an additional switch like -C that allows the program to set the current working directory when started.

With regards to a command-buffers's current working direcotry, there one additional detail to pay attention to: when the command buffer is reused.

Often what happens is that you may find yourself running the debugger on a given program over and over again, even if the debugger has a "restart" or "run" command to do this without leaving the existing session.

When this happens, rather than create fresh new buffers for each invocation, realgud uses the last one if there is one that matches the name it created automatically. That makes it easier to look at past history or find breakpoints settings that you may want to reissue.

When a buffer is reused, it keeps the current working directory of what it had before. There are occasions where that's not what you want: in particular, if the working directory wasn't set right the last time.

When that happens, the simplest thing to do is to delete the process/command buffer that has the wrong working directory and start again. There's probably an elisp function that will change the working directory if that's what you'd prefer to do instead.

Backtrace buffer

I've been working on a backtrace buffer. To get that set up, issue from a debugger command window:

M-x realgud:backtrace-init

Or in a source buffer in short-key mode:

M-x realgud:window-bt

which is by default bound to the key "F" (for frame).

While in the debugger, you will see one or more arrows to the left of the source code. These arrows indicate stop positions. They show the current position in the source code as well the debugging sequence followed. The bottommost arrow indicates the current position within the source code. Other indicators show previous stop points.

Editor marks in the source buffer

In the image, we see that the bottom arrow (green) is at the definition of main(). This is the current position of the debugger. The other arrows indicate previous stop positions. The middle arrow (orange) indicates the previous stop position. The top arrow (pink) shows the position before last. If we were to press n, the green arrow would move down to the if statement, the orange arrow would move to main(), and the pink arrow to class.

This behavior was obtained by progressively "next"-ing through the debugger (n-n-n). Had we executed a different sequence, the arrows would be positioned to indicate that. For example, the sequence n-n-s would position the bottom arrow at main(), the middle arrow at def say_hello(), and the top arrow at class. Thus, the arrows indicate how the debugger has been used.

Stop position arrows are also visible in the debugger window next to the corresponding command.