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

assert examples

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)

  1. Track the problem in the database
  2. Reproduce the failure
  3. Automate and simplify the test case
  4. Find possible infection origins
  5. Focus on the most probably origins:
    • Known infections
    • Causes in state, code, and input
    • Anomalies
    • Code smells
  6. Isolate the infection chain
  7. 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

References