# 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
```none
use Devel::Peek;
my $x = 42;
Dump($x);
```
A minimal `Dump($x)` for a plain integer looks like this on
`STDERR`:
```none
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 `CV`s. 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`](Peek/Dump.md)
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`](Peek/DumpArray.md)
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`](Peek/SvREFCNT.md)
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`](Peek/DeadCode.md)
Report scalars «frozen» into inactive code references — a deep-internals probe for leaks inside closed-over `CV`s.
#### `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`](Peek/DumpProg.md)
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`](Peek/mstat.md)
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.