Introduction to Debugging
Fundamentals on Computing for Robotics, Graphics and Computer Vision
Darío Suárez - Adolfo Muñoz
Introduction to Debugging
http://www.phdcomics.com/comics/archive.php?comicid=673
Goals
- Able to autonomously debug programs in C++
- Debugging from a practical point of view, how to
- More formal aspects and hardware support not covered
- Use other tools, i.e.; linters, to reduce bugs
Digression: use of the library
- biblioteca.unizar.es provides plenty of useful resources
- Quick task: Download Why Programs Fail from the library
Asserting in C/C++
- Check whether a condition holds. Useful to verify pre and post-conditions
- E.g., verify than the size of an array is larger than 0
- Dynamic asserts inherited from c, include the
header
assert(condition)
is a macro
static asserts
- C++11 introduced static asserts checked at compile time
- Powerfull tool with templates
Contracts in C++26
- C++26 will provide a better form of assertions: contracts
- Contracts allow to specify pre-, post-conditions and invariants
- Please stay tunned
Program Execution Flow with Bugs
Why Programs Fail
Seven Steps in Debugging (TRAFFIC)
- Track the problem in the database
- Reproduce the failure
- Automate and simplify the test case
- Find possible infection origins
- Focus on the most probably origins:
- Known infections
- Causes in state, code, and input
- Anomalies
- Code smells
- Isolate the infection chain
- Correct the defect
Source: Why Program Fail, chapter 1.3
Why use debuggers
- Loggers require to change programs
- Potencial to affect behaviour
- Development cost
- Debuggers hook into the running application to observe behaviour
- Debuggers enable to analyze the application at any given time
- Debuggers can affect behaviour as well
Benefits of debugging
- Fast start: Right after a crash, the debugger can start the faulty application
- Flexibility: Ability to observe all the aspects of the execution
- Transient sessions: Single shots allow to iterate over and over
Disclaimer
- The gdb part assumes using gdb directly on Linux
- Gdb support on VS code on windows is possible
GDB basic commands
help <command>
: show information on every command
break
: set a break point, you can use function names, code lines, ...
run
: launch the execution of a program
set args
: set the execution arguments, no effect after run
quit
: exits the debugger
GDB basic commands continuation
cont
: continue current execution
next
: execute a single step entering in methods, subroutines, ...
step
: execute a single step NOT entering in methods, subroutines, ...
list
: print the source code of the program
Please remember that most of these commands have arguments, you can check with info <command>
Some extra GDB commands
backtrace
: prints an stacktrace of the running program
where/info stack
: synonims of backtrace
finish
: run until the current function/method finishes
delete <id>
: removes an specific breakpoint
The powerfull info
command
info <about>
shows information on every aspects of the program
- List of possible
<about>
options:
(gdb) info
address copying inferiors program sources type-printers
all-registers dcache line record stack types
args display locals registers static-tracepoint-markers variables
auto-load extensions macro scope symbol vector
auxv files macros selectors target vtbl
bookmarks float mem set tasks warranty
breakpoints frame os sharedlibrary terminal watchpoints
checkpoints frame-filter pretty-printer signals threads win
classes functions probes skip tracepoints
common handle proc source tvariables
Conditional breakpoints
- Add a constraint that fires the breakpoint when true
- Enables to stop at the required time
break source_file.cpp:279 if ptr == nullptr
Pointers and gdb
- Gdb provide syntax to common pointer operators:
dereference (*), address-of (&), dot (.), and arrow (->)
- Examples:
(gdb) print &var
(gdb) print struct_ptr->field
Debugging multi-threaded programs
Expecial features for multi-threading
- Thread creation notification
thread <id>
: switch to <id>
thread
thread apply [id-list | all ] <command>
: execute the commands on the given list of threads
- Breakpoints per thread