EECS E6870: Speech Recognition
March 16, 2016
What is a debugger, and why use one?
For those of you who are not robots or cyborgs, you will undoubtedly
introduce bugs into your source code at some time or another. One
simple way to debug stuff is to place
Which debugger are we going to use?
The canonical C++ debugger on Linux systems is the GNU
gdb debugger, a command-line
debugger. While there exist GUI wrappers for
gdb, we have no idea
how to use them because we are old-school.
First, compile the program with debugging information on
This is the default in the
Makefile's supplied by us. (When
is invoked, the
flag should be present.)
If you have compiled a program with optimization on (as is sometimes
done in the later parts of labs), then you should run
and then recompile the program.
flag with scripts, if available
If a script runs only a single command, then the
be used with the script to launch that command in the debugger, e.g.,
Otherwise, it's a little more complicated
flag is not available for scripts that run multiple commands.
In this case, run the script with the prefix
to see what commands
are being run, e.g.,
Then, select which command you want to debug, and run that command with the prefix
bash -x lab3_p2a.sh
dbg.sh. For example, to debug the last command run in the preceding script, you would run
dbg.sh lab3_lm --vocab lab3.syms --train minitrain.txt \ --test test1.txt --delta 0.0001 --n 3 --word_probs p2a.3.probs
flag described in the last section just calls
What's going on underneath The normal way to invoke the debugger is as follows:
However, you cannot provide command-line arguments for
my_progwhen you do this; instead, they must be supplied as arguments to the
runcommand described below. This is inconvenient, so we supply a wrapper script
dbg.shthat lets you directly invoke the debugger with command-line arguments. It also sets a couple of useful breakpoints.
To start your program the first time — Use
one uses the
run command to start execution, but
dbg.sh starts your
program for you and stops it when your
main() function is reached.)
To restart your program — Use
gdb — Use
A basic technique in debugging is to stop the execution of your program at strategic points and to examine the values of variables to make sure they are correct. In this section, we discuss different ways of stopping execution.
When an error occurs Your program will automatically stop when
there is a segmentation fault, an assert failure, or an exception.
(For the latter conditions,
dbg.sh sets breakpoints for you.)
Setting breakpoints You can specify a particular line where a program
should stop using the
b command. For example,
will cause execution to stop whenever line 92 in the file
lang_model.Cis hit. Then, you can use the
ccommand to continue execution until a breakpoint is hit.
To skip breakpoints — A numeric argument can be supplied
cont command to skip breakpoints. For example,
will ignore the first four times a breakpoint is hit and then stop at the fifth.
To list breakpoints — Use the command
To delete a breakpoint — Use the
d command. For
deletes breakpoint number 7.
To advance a single line — Use the
command, or the
n command. When a function call
is encountered, the former command will step into the function;
i.e., the current line will be the first line of the function body.
next, the current line will be the first line after the
To advance to the end of the current function — Use the
Selecting a stack frame When you examine a local variable, the debugger displays the local variables of the current function. Normally, the current function is set to what you want, but if execution is stopped due to an assert failure or exception, then the current function will be set to the corresponding C++ library function. In this case, what you want to do is set the current function to be the function that called the current function. This can be done with the following command:
This tells the debugger to
popup one function in the call stack. More generally, the command
can be used to print the whole call stack, and the commands
downcan be used to move up and down in the call stack.
Printing variables To print a variable, use the
p command. Here are example print commands:
As you can see,
p wordCnt p this->m_n p m_n p (*this)->m_n p (*this)->m_n + 5
gdbcan evaluate complex C++ expressions. You can also examine vectors, e.g.,
p ngramBuf.size() p ngramBuf
For more information You can use the built-in command
or look at a
gdbtutorial and there's always Google.
help. To start
gdb <program>. Within
run <arguments> to start the program. Commands
that you should know about include
Don't forget to compile your program with the
(see Section ??).