GDB
under Emacs
Emacs
)
Today's plan is to walk-through how to compile programs under
emacs
,
and also how to debug using gdb
under emacs
.
If you decide to use emacs
for coding, you can optionally
put a configuration/preferences file in your home directory (call it
".emacs", and give it r+w permissions to the world). For the
purposes of today's lab, please use a copy of my
.emacs file.
As well, the program that we will be compiling & debugging can be downloaded from here.
Since not all of you have previous experience with emacs
,
we will briefly review the basics that you'll need to know.
If you are already familiar with emacs
, you can skip this
section.
emacs
is prompting you for information at the bottom of the screen),
then you can abort/cancel by typing C-g (CTRL & g).
emacs
window. Pressing
the "insert" key toggles the overwrite/insert mode
(and is displayed at the bottom of the emacs
window).
The standard way to invoke the compiler is to type: "M-x compile".
You then specify the compile command you want to use (in our case, type
in "g++ -g prob.c -o prob". Thereafter, emacs
remembers and reuses your compile command.
As a shortcut (and thanks to the .emacs file we copied at the beginning), you can just type C-c C-v.
Once you compile, the emacs
window automatically divides
into 2 separate windows. The top window is your source code, and the
bottom window is your interface to the compiler. If you want to remove
the bottom window, click on the top window and then enter "M-x 1"
With 2 separate windows, you can toggle control between the windows by typing "C-x o".
Ok, at this point to the following:
Once the program compiles successfully, we can advance to the next level: debugging.
Do:
emacs
asks you for the exact debug command. Enter
"gdb a.out" (or whatever the name of your executable is).
malloc
. Hmm. Nothing unusual looking.
How about we add a breakpoint, and try tracing through the code
just before the error?
In the bottom (gdb) window, type: break initializeArray
.
This adds a breakpoint at the start of the function. To confirm
the breakpoint, in the gdb window, type: info breakpoints
.
run
. The gdb program asks for confirmation, and then
re-executes, this time stopping as soon as the initializeArray
function is entered.
i
.
In the gdb window, enter: display i
. To confirm that
this was successful, we can type: info display
.
for
expression.
break
command to set a breakpoint
(like we did above), we'll instead use an emacs shortcut. Inside
the source code window, click on line 58 (this is the closing brace
for the for
loop). Enter C-x and then press the [space] key.
This sets a breakpoint at that line. Again, to confirm this, you can
use the gdb command "info breakpoints".
cont
(or continue
) in the gdb window.
i
is displayed as 0.
malloc
line, indicating a segmentation fault.
Hmm. That's funny. That line of code executed fine on the first iteration.
What would cause it to die on the 2nd iteration?
After some hair-scratching, it suddenly hits me that the myArray
structure is being referenced by the wrong syntax. It is a parameter being
passed by reference, and references a list of pointers
to structures. We need to replace all occurrences of *(myArray[i])
with (*myArray)[i]
.
run
. The program stops at the first breakpoint.
Being reasonably confident that we solved the problem, we can remove the breakpoints
by typing:
info breakpoints
,
delete 1 2
,
run
quit
to terminate the gdb application. Click
on the source code window, and enter C-x 1 (to remove the gdb window).
We can now continue with our coding..