This talk is about a unique way in which debuggers can be written in language which are lisp like.
With CIDER debug as an example, this talk takes you through how this approach works under the hood.
This talk was presented at Functional Conf 2019.
GDB - GNU Debugger • Debugger runs as a separate process • Spawns the target program as a child • Examines state with process tracing calls • Implementing breakpoints is a trick! • Puts invalid instructions on breakpoints • Processor traps OS • OS signals the process which caused it • It passes the signal to its parent (GDB) • GDB checks IP and breaks • Some processors support breakpoints GDB Target OS Processor
GDB - GNU Debugger • Dependence on OS for process tracing • Dependence on OS for signals • Dependence on processors for interrupts GDB Target OS Processor
Lisps • Lisp has minimal syntax • Code is data • Code itself is a valid AST • Debuggers can use code as data (map sq-root (filter even? numbers)) map sq-root filter numbers even?
How does it work? 1. Walk through code 1. Mark forms/symbols with coordinates 2. Expand macros 3. Walk through code 1. Wrap forms/symbols with pre-breakpoint macro 4. Pre-breakpoint macro expansion 1. Put a breakpoint if necessary When a function is marked for debugging
How does it work? 1. Necessary information is sent to client 1. Coordinates 2. Return value at current position 3. Values of local vars 4. Possible actions 2. Waits for response from client. . . When a breakpoint is hit
How does it work? 1. Walk through code 1. Mark forms/symbols with coordinates 2. Expand macros 3. Walk through code 1. Wrap forms/symbols with pre-breakpoint macro 4. Pre-breakpoint macro expansion 1. Put a breakpoint if necessary When a function is marked for debugging
How does it work? 1. Walk through code 1. Mark forms/symbols with coordinates 2. Expand macros 3. Walk through code 1. Wrap forms/symbols with pre-breakpoint macro 4. Pre-breakpoint macro expansion 1. Put a breakpoint if necessary When a function is marked for debugging
How does it work? 1. Walk through code 1. Mark forms/symbols with coordinates 2. Expand macros 3. Walk through code 1. Wrap forms/symbols with pre-breakpoint macro 4. Pre-breakpoint macro expansion 1. Put a breakpoint if necessary When a function is marked for debugging
How does it work? 1. Walk through code 1. Mark forms/symbols with coordinates 2. Expand macros 3. Walk through code 1. Wrap forms/symbols with pre-breakpoint macro 4. Pre-breakpoint macro expansion 1. Put a breakpoint if necessary When a function is marked for debugging
How does it work? 1. Necessary information is sent to client 1. Coordinates 2. Return value at current position 3. Values of local vars 4. Possible actions 2. Waits for response from client. . . When a breakpoint is hit
How does it work? 1. Necessary information is sent to client 1. Coordinates 2. Return value at current position 3. Values of local vars 4. Possible actions 2. Waits for response from client. . . When a breakpoint is hit
cider-debug • Bozhidar Batsov • Artur Malabara • Vitalie Spinu • Chris Perkins • Neil Okamoto • Michael Griffiths • Lars Anderson • Dominic Monroe Thank you!