Backtrace is the most common way to understand where a program currently is stopped. Also known as a stack trace, backtrace crawls up the stack in memory to output the current function heirarchy.
Here is an example backtrace. The #0 is the function that contains the currently executing code and #1 is the function that contains the #0 function and so forth up to #3 which is the top-level main function.
(gdb) backtrace
#0 mp_hal_stdin_rx_chr () at mphalport.c:144
#1 0x0001bf6a in readline ([email protected]=0x20007fc8, [email protected]=0x2aeca ">>> ") at ../lib/mp-readline/readline.c:425
#2 0x0001b8d0 in pyexec_friendly_repl () at ../lib/utils/pyexec.c:412
#3 0x0001641a in main (argc=, argv=) at main.c:206
Not only does the backtrace include the names of the functions but it also includes the value of the arguments. For example, the backtrace above shows the prompt argument of readline was ">>> ", just like a Python prompt.
This is really cool but you can do even more. You can also see the state of global and local variables using print
.
Printing
Globals
Printing globals is easy because they are accessible from anywhere. So, simply do:
(gdb) print usb_rx_count
$1 = 0 '\000'
This means the value of usb_rx_count
is 0
.
Locals
Printing locals is a little bit tricky because they are limited by scope. Lets see how we can print prompt
from within the function. This takes two steps, first we must switch frames to the function that has prompt
in the backtrace its #1 and then we can print prompt
.
(gdb) frame 1
#1 0x0001c216 in readline ([email protected]=0x20007fc8, [email protected]=0x2b20a ">>> ") at ../lib/mp-readline/readline.c:425
425 int c = mp_hal_stdin_rx_chr();
(gdb) print prompt
$2 = 0x2b20a ">>> "
Awesome! So now we can understand what function(s) we're in and the current local and global state.