# Breakpoints, actions, and watches This chapter covers stopping the debugger at a specific point — a line, a subroutine, a condition, a value change — and the prompt-hook machinery that lets you run code automatically at each stop. Readers arriving here know how to launch `perl -d` and step one line at a time. The next skill is to skip straight to the interesting place and stop only when the problem is about to manifest. ## Breakpoints on lines and subs | Command | Effect | |----------------------|--------| | `b` | Breakpoint on the current line. | | `b LINE` | Breakpoint at LINE in the current file. | | `b LINE COND` | Conditional; break when COND is true. | | `b FILE:LINE` | Cross-file; FILE matches a `%INC` entry. | | `b FILE:LINE COND` | Conditional cross-file. | | `b SUB` | Break at the first line of SUB (SUB must be compiled). | | `b SUB COND` | Conditional sub breakpoint. | | `b $coderef` | Break at the sub referenced by `$coderef` (no COND supported). | | `b compile SUB` | Break after SUB finishes compiling, before its body runs. | | `b postpone SUB` | Break the first time SUB is called, even if not yet loaded. | | `b load FILE` | Break when FILE is `require`d / `do`'d. | | `B LINE` | Delete breakpoint at LINE. | | `B *` | Delete all breakpoints. | | `disable [FILE:]LINE`| Disable without removing. | | `enable [FILE:]LINE`| Re-enable. | | `L` | List breakpoints, actions, and watches. | | `L b` | List breakpoints only. | Conditions are **raw expressions**, not `if (…)`: ``` DB<1> b 237 $count > 10 DB<2> b 42 /unauthorized/i DB<3> b validate_payload ref($obj) eq 'HASH' && keys %$obj ``` Breakpoints settle only on lines that contain executable code. A blank line, a pure comment, or a continuation of an earlier statement refuses: ``` DB<1> b 3 Line 3 not breakable. ``` A line carries one breakpoint and one action at most; adding a second overwrites the first. ## Timing matrix Where in the program lifecycle a breakpoint fires matters — especially for code in `BEGIN` blocks or modules that are `require`d lazily. | Goal | Command | |------------------------------------------------------|---------| | Stop at the first runtime statement | Default — the debugger already stops there. | | Stop inside a `BEGIN { }` block | Insert `$DB::single = 1;` inside the block. | | Stop before a sub's body runs (after it compiles) | `b compile SUB` | | Stop on first call of a sub not yet loaded | `b postpone SUB` | | Stop when a file is `require`d or `do`'d | `b load /full/path/from/%INC` | | Stop at a specific line | `b LINE` | | Stop at a line only when a condition holds | `b LINE COND` | `$DB::single = 1;` inside a `BEGIN` block is the trick for compile-time debugging: writing `b` at the prompt only works after the debugger is running, but `BEGIN` code runs before the first prompt. Drop the assignment into the block, launch under `-d`, and the debugger stops at the next breakable line inside the block. Accessing `$DB::single` when not under `-d` autovivifies `DB::` harmlessly — the pattern is safe to commit. ## Listing and managing breakpoints ``` DB<1> L app.pl: 42: $user = User->load($id); break if (1) 91: dispatch($req); break if ($req->method eq 'POST') DB<2> disable 42 DB<3> enable 42 DB<4> B 42 DB<5> B * ``` `disable` / `enable` toggle a breakpoint without forgetting its condition — useful when you want to skip a hot breakpoint temporarily and re-arm it later. ## Actions: run code automatically at a line An **action** runs Perl code before the specified line executes, without stopping. Use for passive observation: ``` DB<1> a 42 print "entering: user_id=$user_id\n" DB<2> a 91 warn "POST body:\n" . Dumper($body) if $req->method eq 'POST' DB<3> L a app.pl: 42: ... action: print "entering: user_id=$user_id\n" DB<4> A 42 # delete action at line 42 DB<5> A * # delete all actions ``` Ordering at a breakable line: 1. Breakpoint condition is tested. 2. Trace output is printed (if tracing on). 3. Action runs. 4. Prompt appears (if breakpoint hit or stepping). 5. The line itself executes. Actions and breakpoints coexist on the same line — one of each maximum. ## Watches: break on value change A watch reports the old and new value when a tracked expression changes, and drops you at the prompt: ``` DB<1> w $global_count DB<2> c Watchpoint 0: $global_count changed: old value: 42 new value: 43 main::tick(app.pl:118): ++$global_count; DB<3> W $global_count # delete this watch DB<4> W * # delete all watches ``` Watches are evaluated at every breakable line. Expressions must reference globals or accessible aliases; lexical `my` variables are not watchable directly. When a lexical matters, use `Tie::Watch` in the code to install a watcher at tie time, or assign via a package-scoped alias. Watches add per-statement cost proportional to the number of watches and the expense of each expression. Keep them narrow and remove them when done. ## Prompt hooks: run code at every stop `<` / `>` install Perl code to run automatically before / after every prompt. `{` / `{{` do the same for debugger commands: | Command | Effect | |------------------|--------| | `< CMD` | Perl code before each prompt (= after the line just executed). | | `<< CMD` | Append to the pre-prompt list. | | `< ?` | List pre-prompt code. | | `< *` | Delete all pre-prompt code. | | `> CMD` / `>> CMD` | Perl code after each prompt (= before next line). | | `{ DBCMD` | Debugger command (not Perl) pre-prompt. | | `{{ DBCMD` | Append to the pre-prompt debugger-command list. | Typical use: timestamp every step: ``` DB<1> < print "stop: ", scalar localtime, "\n" DB<2> > print "start: ", scalar localtime, "\n" ``` Or always show the current line and a watched variable: ``` DB<1> { v DB<2> { p $important ``` Multi-line: escape the newline with `\`: ``` DB<1> < for my $f (@important_files) { \ cont: print " $f: ", (-s $f) // 'n/a', "\n"; \ cont: } ``` ## Aliases Persistent command shortcuts via `=`: ``` DB<1> = len s/^len(.*)/p length($1)/ DB<2> = quit s/^quit(\s*)/exit/ DB<3> = # list all aliases ``` Aliases live in `%DB::alias` and apply at dispatch time. Define once in `.perldb` for across-session persistence. ## One-shot breakpoints `c LINE` sets a breakpoint at LINE, continues, and clears the breakpoint when it hits: ``` DB<1> c 42 ``` Simplest way to say "just run to line 42 and stop there". No manual `b` / `B` pairing. ## Breaking on import / first-call lazily When a sub lives in a module that may not be loaded yet, `b SUB` fails: ``` DB<1> b MyApp::Worker::dispatch Subroutine not yet compiled. ``` `b postpone` waits for the sub to finish compiling: ``` DB<1> b postpone MyApp::Worker::dispatch DB<2> c ``` For files loaded by `require` / `do`, `b load` breaks on first load: ``` DB<1> b load /usr/share/perl5/MyApp/Worker.pm ``` The filename must match the full path in `%INC`, not just the module name. ## Find out more - [inspecting-state](inspecting-state) — what to look at once a breakpoint fires. - [tracing](tracing) — when you want to watch what happens *without* stopping.