Tutorial: Emacs for Programmers

Ever wanted an all-in-one program development, compilation, and debugging environment? Look no further than Emacs.

Running gdb

gdb is the GNU debugger. It
is indispensable for run-time debugging for programs written in
nearly any compiled language, most notably C.
gdb can also be used for
post-mortem examination of a crashed program using a core
file.

Not surprisingly, Emacs provides a number of features which
allow you to run gdb within an Emacs buffer, interacting with the
corresponding source buffers to view and edit code. While gdb
deserves a tutorial of its own, here we will introduce you to the
Emacs-specific gdb features. gdb provides extensive online help,
which can fill in the gaps left here. For the rest of this
tutorial, we assume that you have basic familiarity with gdb, or a
similar debugger such as dbx.

Let's take the following short program, which will
un-doubtedly cause a segmentation fault on most systems:

As you can see, we're attempting to write data into a NULL
pointer. Sure enough, when we compile and run the program, we
obtain:

loomer:~/test/lj/crashme% ./crashme
Segmentation fault (core dumped)

Let's use gdb to inspect the problem. Using M-x
gdb gives us the prompt:

Run gdb (like this): gdb

Here, you should complete the gdb command line. In this case,
we want to run gdb on the executable crashme, with the core file
core. So, we complete as so:

Run gdb (like this): gdb crashme core

Emacs should open two windows—one containing the gdb
interaction session, and the other containing the source file
crashme.c. The gdb session will look something like:

GDB is free software and you are welcome to distribute copies
of it under certain conditions; type "show
copying to see the conditions. There is absolutely no
warranty for GDB; type "show warranty" for
details.

We can now issue gdb commands to inspect the crash.
Immediately, we notice that the crashme.c buffer contains an arrow
pointing to the current source line, as so:

=>data[0] = 1;
data[1] = 2;
/* ... */

This arrow is not part of the source text. It can't be
selected, modified, or deleted. You are free to edit the code in
the source buffer; this imaginary arrow will not be saved with the
edited code. The arrow only exists to let us know what gdb's idea
of the current source line is. Note, however, that adding or
deleting lines from the source buffer will cause gdb's information
about the location of source lines to be out-of-sync with the
actual code.

We can see that the crash was caused by a segmentation fault
on line 5, pointed to by the arrow. Using the where command in the
gdb buffer will give us a stack trace, and so on. You can correct
the code in the source buffer, recompile, test, and re-run gdb (if
necessary), all within Emacs.

gdb can also be used to inspect running programs. For
example, we can run crashme under gdb's control, and step along a
line at a time. First, however, let's correct the bug by changing
the definition of data to

int data[30];

(Otherwise, crashme would crash on the first line of code,
and we'd have scant little to go on by way of
demonstration.)

First, we should set a breakpoint on the first line of code.
Within the gdb buffer, we can use list to display the first few
lines:

Now, the run command will begin execution of the program, but
will halt immediately on the first line of code. A buffer for
crashme.c will be opened, with our friendly arrow pointing at the
line containing the breakpoint.

Now, we can employ gdb's various commands directly, by
entering them in the gdb buffer—or, we can use the Emacs key
equivalents. Placing point on a line of code in the source buffer
and typing C-x C-a C-b will set a breakpoint at
that line. Similarly, C-x C-a C-d will delete
all breakpoints on that line. (The gdb command info break will list
the current breakpoints.) After setting a breakpoint, you can use
C-x C-a C-r to resume execution.

All of the above commands can be used within the gdb buffer
as well, using C-c instead of C-x
C-a as the prefix. For convenience, C-x
SPC in either buffer will set a breakpoint on the current
source line.

If you find these key bindings unnecessarily lengthy, as I
do, you might consider rebinding the functions
gud-break, gud-remove, and
gud-cont within c-mode-map.
For example, I use the commands

Of course, this negates the previous meanings of
M-b, M-d, and
M-r within C Mode.

The following additional macros are available within the gdb
buffer, as well as within C Mode by changing the prefix from
C-c to C-x C-a.

`C-c C-s' Step one line of code,
descending into function calls. (The gdb step command.)

`C-c C-n' Step one line of code,
without descending into function calls. (The gdb next
command.)

`C-c <' Move up one stack
frame. (The gdb up command.)

`C-c >' Move up one stack
frame. (The gdb down command.)

`C-c C-f' Run until the
completion of the current function, and then stop. (The gdb finish
command.)

Again, you may wish to bind these to shorter key sequences
(such as M-s, M-n, and so
on).

Another interesting command is C-x C-a
C-p, which will (within the source buffer) take the C
expression around point and pass it to gdb's print command, which
evaluates the expression and prints its value. This is very handy
way to examine variables, data structures, and so forth within the
debugger. You can even use this command to call functions and print
the return value, if you're executing the debugged program within
gdb.

For example, placing point on the line

printf("Last value is %d\n",data[19]);
and pressing C-x C-a C-p will cause the following to be printed in the
gdb buffer:
(gdb)
$1 = 16

In this case, data[19] is 0, because we haven't executed the
calculation loop yet. Nevertheless, we can call functions within
the program (or, in fact, any arbitrary function, using the print
command manually) and examine the return value.

Emacs also allows you to define your own functions for
interacting with the debugger. For example, we might want to move
the point to a line of code, and run the gdb until function, which
will cause execution to continue until that line is reached.

This is accomplished with the gud-def
function. For example, we can use (gud-def my-until-line
"until %f:%l""\C-u" "Run until current line.")

This will define the function my-until-line which sends the
string

until %f:%l

to the gdb process, where %f is replaced
with the current source filename, and %l is replaced with the
current line number. The new function will be bound to the key
sequence C-x C-a C-u (in the source buffer), and
C-c C-u (in the gdb buffer). The final argument
is the documentation string for the command, printed using
describe-function.

Now, we can place point on a line of code in the source
buffer, type C-x C-a C-u, and execution will
continue until that line of code is reached.

We can customize interactions with the debugger in another
way. For example, gdb lacks the inherent ability to automatically
step along code, allowing us to monitor the execution of the
program without interruption. A similar effect can be achieved by
using the step command many times in succession, but we'd like
Emacs to automate the process for us.

Running this function as M-x
gdb-step-forever will prompt us for the amount of time to
sleep between steps, in seconds. (This need not be an integral
number of seconds—you can specify real values such as 0.5.) The
function will then pause for the given amount of time, run
gud-step, and repeat, ad infinitum. To interrupt
the function, you can use the Emacs quit key,
C-g.

A more general extrapolation of this idea would allow us to
run a “hook” function between steps, which would allow us to print
the values of variables, and so on.

Note that the above function isn't very intelligent—if it
runs into a breakpoint, or the program ceases execution for some
reason, it will continue to loop naively. In these cases, you can
simply interrupt the function by hand.

Given the above tour, you should be ready to tackle the other
programming features that Emacs provides—including version
control, customized indentation styles, and so forth. Perhaps a
future issue of Linux Journal will cover these aspects of
Emacs.

I welcome all suggestions, comments, and corrections for the
material presented here. Please feel free to send correspondence to
the author, c/o Linux Journal, or via electronic mail at
mdw@sunsite.unc.edu
.

Happy hacking!

Matt Welsh
(mdw@sunsite.unc.edu)
is a programmer at the Cornell University Robotics
and Vision Laboratory.He is a writer and programmer who uses vi almost exclusively—perhaps more by accident than design. He spends his free time homebrewing virtual
beer and playing the blues.

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.