Devel::Peek#

📦 min

Inspect the internal representation of any Perl scalar — a debugging tool for working with SVs.

Devel::Peek is the tool you reach for when the question is “what does Perl actually think this value is?”. Typical uses:

  • chasing a refcount leak — something holds a reference longer than you expect, and you want to see REFCNT climb;

  • confirming that a value came back as the type you meant (IV vs PV vs PVMG, a blessed object, a tied scalar);

  • looking at the flags on an SV (POK, IOK, ROK, UTF8, TEMP, OBJECT) to diagnose dual-var, stringification, or tainting surprises;

  • peeking inside arrays, hashes, and references to see how Perl has laid them out and which slots contain what.

Synopsis#

use Devel::Peek;

my $x = 42;
Dump($x);

A minimal Dump($x) for a plain integer looks like this on STDERR:

SV = IV(0xbc818) at 0xbe9a8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 42

Every line is meaningful. SV = IV(...) names the body type. REFCNT is what you stare at when tracking leaks. FLAGS tells you which of the IV / NV / PV slots below it are live; IOK means the IV field is current, POK means the PV field is, ROK means the scalar is a reference and there is another SV = ... block nested below it. Arrays dump with FILL (last index) and MAX (capacity) and then their elements as Elt No. N sub-dumps. Hashes dump with KEYS, bucket occupancy, and one sub-dump per entry.

The entry points:

  • Dump($sv, $depth=4) — dump one value. @array and %hash dump the aggregate itself rather than the first element; other arguments are evaluated in scalar rvalue context.

  • DumpArray($depth, @values) — dump several values in one call, each tagged with its position. Useful when inspecting a function’s return list.

  • SvREFCNT(\$sv) — return the refcount of the referent of a reference (the outer reference itself is subtracted). Pairs well with Dump when you want the number without scraping it out of a dump.

  • DumpWithOP($sv, $depth=4) — same as Dump but also walks into compiled ops when the scalar carries one (a PVCV, for example). Equivalent to setting $Devel::Peek::dump_ops around a Dump call.

  • DumpProg() — dump the program’s main op tree. Aimed at people debugging the compiler, not at regular scripts.

  • DeadCode() — walk the SV arena for scalars frozen into inactive CVs. A deep-internals tool; most users never touch it.

  • CvGV($cv) — return the GV associated with a code reference, so you can recover a sub’s package-qualified name.

The mstat family#

mstat, fill_mstats, mstats_fillhash, and mstats2hash report on Perl’s malloc arena — bucket counts, free/used chunks, sbrk activity. They only produce real numbers when Perl was built with its bundled malloc (rare in modern builds). Under a standard build, mstat prints perl not compiled with MYMALLOC and the hash-filling variants croak with the same message. This is the upstream behaviour, not a pperl limitation; scripts that guard on it already handle the non-MYMALLOC case.

The runops and :opd knobs#

use Devel::Peek ':opd=st' switches the interpreter to its debugging dispatch loop and turns on per-op trace flags (s stack, t trace, P profile). runops_debug() is the runtime toggle for the same switch; debug_flags() reads and writes the $^D letter mask directly. Reach for these when you want to see which ops execute and in what order — they are the programmable equivalent of perl -Dst.

All output from Dump, DumpArray, DumpProg, and mstat goes to STDERR. The global $Devel::Peek::pv_limit caps how many characters of each PV are printed; 0 means no limit.

Functions#

Scalar inspection#

Dump#

Dump one scalar’s internal representation to STDERR. The usual entry point for Devel::Peek; reaches for this first when you need to see what Perl has under the hood.

DumpArray#

Dump several values in one call, each tagged with its index. Useful when inspecting a function’s return list or an argument list without wrapping every element in its own Dump.

SvREFCNT#

Return the reference count of a referent. SvREFCNT(\$x) answers “how many live references to $x exist right now?” — the usual tool for tracking a suspected leak without pulling the number out of a full Dump.

DeadCode#

Report scalars “frozen” into inactive code references — a deep-internals probe for leaks inside closed-over CVs.

DumpWithOP#

Dump a scalar and, if it carries a compiled op tree, the tree itself. Convenient when inspecting a CV (code reference) or any scalar whose interest is partly in its attached ops.

DumpProg#

Dump the program’s main op tree. A compiler-debugging tool, not a value-inspection tool.

CvGV#

Recover the GV (typeglob) associated with a code reference. CvGV($cv) is how you go from an anonymous-looking sub ref back to the name Perl filed it under — useful when inspecting caller frames, dispatch tables, or closures assigned to named slots.

Memory stats#

fill_mstats#

Fill a scalar with a machine-readable snapshot of Perl’s malloc state. fill_mstats($buf) is the cheap member of the mstat family: pair it with mstats2hash later when you actually want to read the numbers.

mstats_fillhash#

Populate a hash with Perl’s malloc statistics. mstats_fillhash(%hash) fills %hash with fields like nbuckets, total, totfree, sbrks, plus the per-bucket free / used / mem_size / available_size array references. See perldebguts for the full field list.

mstats2hash#

Decode a fill_mstats buffer into a hash. mstats2hash($buf, %hash) is the readout step for the buffered form: cheap fill_mstats inside a hot loop, one mstats2hash pass at the end to turn the buffer into inspectable fields.

mstat#

Print a one-line memory snapshot to STDERR. The classic marker-in-a-log tool — sprinkle mstat "Point 5" across a program to see how arena size moves between points.