Debugging Perl programs#
Perl ships with an unusually complete debugging surface: a built-in statement-by-statement debugger, a regex-engine tracer, a documented API for writing alternative debuggers, and a CPAN ecosystem of profilers, leak finders, post-mortem tools, and IDE integrations. pperl’s reimplementation preserves the interpreter’s hook points - $^P, DB::DB and DB::sub fire as they do in perl5 - so perl5’s own debugger, perl5db.pl, runs unchanged where a system perl5 provides it on @INC. Tools that are XS extensions, such as Devel::NYTProf and Devel::Cover, do not load.
pperl -d script.pl starts the debugger, and so do -de0, -d:Module and a #!/usr/bin/perl -d first line; a session is the same as perl5’s. The one exception is -dt: it asks perl5db.pl for thread support, and on pperl’s threadless build that dies with This Perl not built to support threads.
Which chapter do I want?#
Symptom | Start here |
|---|---|
Program misbehaves and I want to inspect it live | |
Program crashes with a cryptic message | |
I want to sprinkle prints and dumps | |
I want to turn more mistakes into compile errors | |
I need to stop on a specific line or condition | |
I need to see what a data structure actually holds | |
I want to see every line / sub as it executes | |
I want breakpoints in VS Code / Neovim |
The three layers of this guide#
Orientation - this page.
Working programmer - the chapters listed above. Each is self-contained; reading a single one is enough to solve the problem it names.
Known gaps#
Debugging surfaces where the ecosystem itself is thin, or where pperl’s implementation has not reached parity with upstream. Named here so readers do not waste time on them.
Regex tracer output format. pperl’s regex engine is a native reimplementation;
use re 'debug'produces a trace but node names and field formats are not byte-identical to perl5’s. Consumers that parse the trace (few exist) will need adjustment.B::*introspection modules. pperl providesBandOnatively.B::DeparseandB::Conciseare pure Perl on top of them: where a system perl5 provides them on@INCthey run under pperl and agree with perl5 on ordinary code. Less-used members of the family reach further into the op graph, where pperl’s representation differs, and may still need adjustment.XS-dependent introspection modules.
Devel::Peek,Devel::FindRef,Devel::Gladiator,Devel::Refcount,Devel::Size,Devel::MAT::Dumper,Devel::Leakfamily - all reach the SV through XS (C-level macros against the SV pointer). pperl mirrors perl5’s SV layout faithfully, but XS loading is not supported; these modules therefore need native (Rust) reimplementations that expose the same Perl-level API. Pure-PerlDevel::Peek-workalike functionality is already provided natively by the built-inDevel::Peek; the others are in progress.Enbuggeron Perl ≥ 5.38. Last release 2012; works anecdotally on modern perls but has no active maintainer. Thegdb-inject-perlpath is more reliable.Async provenance. No Perl equivalent to Node’s
AsyncLocalStorage: aFuturethat fails in a distant callback carries no automatic record of who scheduled it.Sentry breadcrumbs.
Sentry::Ravenis functional but maintenance-only; no first-class breadcrumb support. The OpenTelemetry Perl SDK is the forward path for new installations.Perl::LanguageServerattach-to-running-process. Launch is supported; post-hoc attach is not.
See also#
perlfunc/die,perlfunc/warn,perlfunc/eval,perlfunc/caller- the language primitives the debugger and the stack-trace tools are built on.PPerl Architecture guide - how pperl is built and why the debugger surface works as it does.