## NAME Dawa -- A runtime debugger for Raku programs ## SYNOPSIS In example.raku: use Dawa; my $x = 100; $x = $x + 1; stop; $x = $x + 10000; $x++; $x++; $x++; Then: â Stopping thread Thread #1 (Initial thread) --- current stack --- in block <unit> at eg/example.raku line 6 -- current location -- 1 â â use Dawa; 2 â â 3 â â my $x = 100; 4 â â $x = $x + 1; 5 â [1] â stop; 6 â âś â $x = $x + 10000; 7 â â $x++; 8 â â $x++; 9 â â $x++; 10 â â Type h for help dawa [1]> $x 101 dawa [1]> n 7 âś $x++; dawa [1]> $x 10101 dawa [1]> n 8 âś $x++; dawa [1]> $x 10102 dawa [1]> c ## DESCRIPTION Dawa provides functionality that is inspired by Ruby's [pry](https://github.com/pry/pry) and Python's [import pdb; pdb.set_trace()](https://docs.python.org/3/library/pdb.html) idiom. It exports two subroutines: `stop` and `track`, which work as follows: * `stop` will pause execution of the current thread of the program, and allow for introspecting the stack, and stepping through subsequent statements. * `track` will allow any thread which executes this line of code to be tracked; the position and stack of all threads which go through this statement can be viewed while the debugger is active. Using this module is heavy-handed -- currently just the `use` command will add a lot of unused extra statements to the AST. (This implementation may change in the future.) ## USAGE After `stop` is reached, a repl is started, which has a few commands. Type `h` to see them. Currently, these are the commands: break (b) : [N [filename] ] add a breakpoint at line N [in filename] continue (^D, c) : continue execution of this thread eval (e) : evaluate code in the current context help (h) : this help ls (l) : [-a] show [all] lexical variables in the current scope next (n) : run the next statement threads (t) : [id] show threads being tracked [or just thread #id] where (w) : show a stack trace and the current location in the code Pressing [enter] by itself on a blank line is the same as `next`. Anything else is treated as a Raku statement: it will be evaluated, the result will be shown. ### Breakpoints Breakpoints can be set with `b`, for example: dawa [1]> b 13 Added breakpoint at line 13 in eg/debug.raku dawa [1]> w ... 9 â [1] â stop; 10 â â 11 â âś â say "three"; 12 â â say "four"; 13 â â â $x = $x + 11; 14 â â say "five"; As shown above, breakpoints are indicated using `â ` in the code listing, and are not thread-specific. The triangle (âś) is the next line of code that will be executed. The `[1]` indicates the last statement executed by thread 1. The `[1]` in the prompt indicates that statements will currently be evaluated in the context of thread 1. ## Multiple Threads If several threads are stopped at once, a lock is used in order to only have one repl at a time. Threads wait for this lock. The id of the thread will be in the prompt, as shown above. The `track` statement can be used to keep track of threads without stopping them. For instance, this code shows the debugger stopped in thread 1, but indicating the current statement in thread 7 that is being executed: â Stopping thread Thread #1 (Initial thread) --- current stack --- in block <unit> at example.raku line 11 -- current location -- 3 â â my $i = 1; 4 â â 5 â â start loop { 6 â â $i++; 7 â [7] â track; 8 â â } 9 â â 10 â [1] â stop; 11 â âś â say 'bye!'; 12 â â Type h for help dawa [1]> Note that in this situation thread 7 continues to run even while the repl is active. To also stop thread 7 while debugging, you can add a breakpoint (since breakpoints apply to all threads). ## ABOUT THE NAME The word `dawa` can refer to either medicine or poison in Swahili. In the latter sense, it would be used to describe bug spray, i.e. a debugger -- but hopefully it'll also help be a cure for any ailments in your programs. ## SEE ALSO 1. There is a built-in `repl` statement, which will pause execution and start a repl loop at the current location. 2. [rakudo-debugger](https://github.com/jnthn/rakudo-debugger) provides a separate executable for debugging. Techniques there inspired this module. ## ENVIRONMENT The readline history is stored in `DAWA_HISTORY_FILE`, ~/.dawa-history by default. ## BUGS The `stop` routine won't work if it is the last statement in a file. There are probably other bugs -- let me know and send a patch! Also a mailing list is available to discuss features and send patches: https://lists.sr.ht/~bduggan/raku-dawa ## AUTHOR Brian Duggan (bduggan at matatu.org)