# Before we begin, update your VM... ## Ensure all local packages are up to date - **FIRST SET A CHECKPOINT FOR YOUR VM** - `sudo apt-get update` ## Upgrade/Install some packages - `sudo apt-get upgrade -y gdb` - `sudo apt-get install -y python3-pip` - `pip3 install --upgrade pip` --- # Tips and Tricks Update - Edit your `~/.ssh/config` to contain the following (works on MacOS, Linux, VM, and WSL) ``` ### CAEN Host caen login.engin.umich.edu HostName login.engin.umich.edu User mmdarden # Use your own uniqname ControlMaster auto ControlPath ~/.ssh/_%r@%h:%p ControlPersist 43200 Host mmd # Use your own initials or fave shortcut HostName oncampus-course.engin.umich.edu User mmdarden # Use your own uniqname ``` --- # Tips and Tricks Update - When connecting to CAEN (with `ssh caen`) - First login requires password and DUO - Subsequent logins connect instantly (for 12 hours, or until...) - When the multiplexing expires or is broken (rules unknown) - Works for everything that uses ssh (commands, sessions, 3rd party software, etc.) - 2 useful commands - `ssh -O check caen` - `ssh -O stop caen` - Also, look for the file `~/.ssh/_mmdarden@login.eecs.umich.edu:22` --- # TTU++ - Connect your local dev environment to CAEN - Use `rsync` and a "Post-build script" - EECS 281 example: [https://gitlab.eecs.umich.edu/eecs281/makefile] - Look at `$(REMOTE_BASEDIR)` - Look at `$(REMOTE_PATH)` - Look at target `sync2caen` - Xcode example: - Edit Scheme... - Add a "Build Post-action" - Name: "Sync to CAEN" - Shell: `/bin/bash` - Provide build settings from: `
` - Add the following script ```bash # Auto upload from Xcode to CAEN make -C "${SRCROOT}" sync2caen > "${SRCROOT}/rsync.log" open "${SRCROOT}/rsync.log" ``` - Check on CAEN in `~/$(REMOTE_PATH)` - Sync happens after every successful build! --- ![Edit Scheme: Build Post-action](img/postbuild.png) --- class: center, middle # Debuggers .copyright[
> ** [Pat Pannuto](http://patpannuto.com) / Marcus Darden ** ] --- # What Does gdb Do? ## Yes - Start your program (with options and arguments) - Stop your program - Allow you to see into registers and memory - Allow you to change values manually during execution -- ## No - **MAGIC** ??? A debugger is a program than runs another program. This lets the debugger (the parent) stop, start, or modify the program that is being debugged (the child, target, or inferior). --- # How Do I gdb? To debug a program with gdb, simply put `gdb` in front of the program, i.e.: -- ```bash > ./prime # running normally > gdb ./prime # debugging the program with gdb ``` -- One annoying gotcha shows up if the program to debug takes any options. The simple prime program does not, but if it did: ```bash > ./prime --imaginary-option # running normally > gdb ./prime --imaginary-option # will not work gdb: unrecognized option '--imaginary-option' > gdb --args ./prime --imaginary-option # gdb will ignore everything after --args ``` --- # GDB's Text User Interface * It's a CLI program, get over it! * Nope... Beast Mode... GDB TUI * At launch with --tui * After launch with `C-x 1` -- ## GDB TUI Key Bindings (partial) | Binding | Action | | --------- | ------------------------------------------------------ | | `C-x a` | Enter/exit TUI | | `C-x 1` | Change TUI layout? | | `C-x 2` | Change TUI layout | | `C-x o` | Switch window focus | | `C-x s` | Single Key mode | | `C-l` | Refresh screen | | `C-p`, `C-n`, `C-b`, `C-f` | Readline navigation (Emacs FTW!) | | --------- | ------------------------------------------------------ | --- # GDB TUI Single Key Mode * This is truly GDB Beast Mode... on steroids! | Key | Action | | --- | :----------------------- | | c | continue | | d | down | | f | finish | | n | next | | q | exit the Single Key mode | | r | run | | s | step | | u | up | | v | info locals | | w | where | | --- | ------------------------ | --- # gdb Commands ## `run` - Starting gdb will not run your program by default. You must use the `run` command to begin execution. - Using `run` will start your program with the options originally specified, or you can pass new options with `run`. ```bash (gdb) run --different-option ``` - If your project is recompiled, each `run` will automatically reload the new version. Debugging is easier if you don't quit gdb, but leave it running in a separate terminal. --- # gdb Commands ## `backtrace`, `up`, `down`, `frame`, `print` - While your program is running, it has a function call stack that is built up with frames that hold parameters, locals, and register information for each invocation. Consider math.c: .column-66[ ```C #include
int subtract (int a, int b) { return a - b; } int divide (int a, int* b) { return a / *b; } int do_math (int x, int y, int z) { int temp = subtract(x, y); temp = divide(z, &temp); return temp; } int main () { int temp; temp = do_math(10, 10, 20); printf("Result: %d\n", temp); return 0; } ``` ] .column-33[ Function call stack (growing to the right) main main -> do_math main -> do_math -> subtract main -> do_math main -> do_math -> divide ] --- # gdb Commands ## `list`, `break`, `continue`, `step`, `next`, `set` - Look at your source with `list` or `list
` -- - Stop and start your program with `break` and `continue` -- - Take things at your own pace with `step` (into) and `next` -- - Make a change to variables and registers with `set` --- # More on breakpoints - Generally specified by filename:linenumber - Will also work in context - List all current breakpoints with `info breakpoints` - Remove with `delete
` or `disable
` until later - Skip over working code with breakpoints on either side and `continue` --- # GDB Does Python!! * Access to GDB internals * Variables, functions, etc. * Inline, short entry, and script * A pretty printer ```python class ObjectPrinter: '''Pretty print an Object''' def __init__(self, val): self.val = val def to_string(self): '''Change this to reflect real properties from the object''' return self.val def lookup_type(val): if val == 'Object': return ObjectPrinter(val) def display_hint(self): return 'Object' gdb.pretty_printers.append(lookup_type) ``` --- # The New Hotness... gdbgui - `pip3 install gdbgui --upgrade` - Rerun the previous debug session - Start a new debug session --- # Open Problems with Debugging ## Look at `inf.c`