Using the Debugger
Overview
Some terminology:
lldbis a command-line debugger- “LLVM” is the compiler framework that includes many things, including the
clangcompiler that we are using, as well aslldb gdbis the debugger that was used in the past, and is often used elsewhere – it is analogous tolldbin how it works
What is a Debugger?
A debugger is a utility program that allows you to run a program under development while controlling its execution and examining the internal values of variables. We think of a program running “inside” a debugger. The debugger allows us to control the execution of the program by pausing its execution and then resuming it. While paused, we can find out where we are in the program, what values variables have, reset the values of variables, etc. If a program crashes, the debugger can tell you exactly where the program crashed. The principles and commands described in this document are specific to the lldb debuggers under UNIX, but every debugger has similar commands.
Compiling for Debugging
We’ll use debuggers initially on binary files. When we get to writing our own C code, you will want to compile your code with the -g flag to enable debugging symbols, which will make the debugger much more useful.
How to Start Using lldb
- Log into a computer with clang and LLDB that uses the x86-64 ISA (i.e., by SSHing into
portal.cs.virginia.edu) - Invoke1 with
lldb program_to_debug. Note: you must runlldbon an executable. You cannot runlldb distance.s; you must assemble your file withclangfirst.
The following sections describe the important types of things you can do with lldb, organized by “category” of activity.
Useful commands
The following all assume you are in a debugger
Commands controlling running
| Command | Meaning |
|---|---|
run | (re)start the program |
run x y z | (re)start the program with command line arguments x, y, and z |
step | step one source-code-line forward, entering functions if stepping on call |
next | step one source-code-line forward, skipping to return if stepping on call |
stepi | step one ISA-instruction forward, entering functions if stepping on call |
nexti | step one ISA-instruction forward, skipping to return if stepping on call |
finish | run until the next return |
continue | resume running after run was interrupted (e.g., after a breakpoint or step). |
exit | leave the debugger |
You might also want to use Ctrl+C to interrupt a program if it is running too long (this works on the command line for programs run without a debugger too).
Commands controlling break points
A breakpoint is a program location where the debugger pauses when running so you can see what’s around it.
When run, the debugger pauses right before executing the code on which you place a breakpoint.
| Command | Meaning |
|---|---|
br set -n main | set a breakpoint on the first line of main |
br foo.c:23 | set a breakpoint on the line 23 of foo.c (must be a line with code, not a comment, blank line, etc) |
br list | list all breakpoints |
br delete 1 | delete breakpoint number 1 (as indicated in the list) |
Looking around
To inspect the code and call stack,
| Command | Meaning |
|---|---|
bt | show a backtrace: a list of calls used to reach here |
up | select the stack frame of the caller of the current stack frame |
down | undo a previous up |
di -f | diassemble the code for the current call frame. |
di -n main | diassemble the code for the function named main |
di -n main -b | diassemble the code for the function named main, with byte encoding of instructions included |
di -s 0x1234 -c 20 | diassemble 20 bytes starting at address 0x1234 |
If you need to peek inside registers or memory,
| Command | Meaning |
|---|---|
frame info | show information about the current stack frame |
register read | show the contents of the program registers |
register read --format i | show the contents of the program registers, formated as signed integers |
register read rax rdx | show the contents of rax and rdx (only) |
me rea -s4 -fx -c8 0x1234 | memory read, with a count of 8 values, each value’s size being 4 bytes, formated in hexadecimal, from address 0x1234 |
Example: debugging cmdadd
See the cmdadd example for a detailed walkthrough.
-
If you have issues running
lldb, it could be that you did not run the script from Lab 1. You may load the module containinglldbon the portal by first running the commandmodule load clang-llvm. ↩