PERLDTRACE(1perl)

πŸ“¦
version 5.44.0 Β· 2 versions
, in arch rolling

✨ PERLDTRACE ✨ (perl's DTrace era)

okay bestie, this is the page for perldtrace β€” Perl's support for DTrace πŸ’… it lives in the Perl Programmers Reference Guide, and it's genuinely one of the most main-character things in the whole perl toolkit.


πŸ’– NAME πŸ’–

perldtrace β€” Perl's support for DTrace


🌸 SYNOPSIS 🌸

like, here's the vibe in action:

# dtrace -Zn 'perl::sub-entry, perl::sub-return { trace(copyinstr(arg0)) }'
dtrace: description 'perl::sub-entry, perl::sub-return ' matched 10 probes

# perl -E 'sub outer { inner(@_) } sub inner { say shift } outer("hello")'
hello

(dtrace output)
CPU     ID                    FUNCTION:NAME
  0  75915       Perl_pp_entersub:sub-entry   BEGIN
  0  75915       Perl_pp_entersub:sub-entry   import
  0  75922      Perl_pp_leavesub:sub-return   import
  0  75922      Perl_pp_leavesub:sub-return   BEGIN
  0  75915       Perl_pp_entersub:sub-entry   outer
  0  75915       Perl_pp_entersub:sub-entry   inner
  0  75922      Perl_pp_leavesub:sub-return   inner
  0  75922      Perl_pp_leavesub:sub-return   outer

πŸ¦‹ DESCRIPTION πŸ¦‹

so DTrace is this whole framework for comprehensive system- and application-level tracing β€” iconic, honestly. and Perl is a DTrace provider, which means it exposes a bunch of probes you can instrument with. you can pair them up with kernel-level probes, or probes from other providers like MySQL, to diagnose software defects, or ngl just to find your app's bottlenecks. πŸ”₯

ok but listen β€” Perl has to be compiled with the -Dusedtrace option for any of these probes to even exist. DTrace aims to have zero overhead when its instrumentation isn't active, but Perl's support itself can't uphold that guarantee, so on most systems it gets built without DTrace probes. the one notable exception? Mac OS X ships a /usr/bin/perl with DTrace support enabled. slay, apple, i guess. πŸ’…

πŸ‘‘ HISTORY πŸ‘‘

here's the glow-up timeline, bestie:

  • 5.10.1
    • Perl's initial DTrace support was added, providing sub-entry and sub-return probes. the origin story ✨
  • 5.14.0
    • sub-entry and sub-return gain a fourth argument: the package name of the function. growth!
  • 5.16.0
    • phase-change was added. new era unlocked πŸŽ€
  • 5.18.0
    • op-entry, loading-file, and loaded-file were added. the full squad fr fr.

🌈 PROBES 🌈

every single one, no skips, no cap:

sub-entry(SUBNAME, FILE, LINE, PACKAGE)

Traces the entry of any subroutine. heads up though β€” all of the variables refer to the subroutine that is being invoked; there is currently no way to get ahold of any information about the subroutine's caller from a DTrace action. sorry bestie, the caller info is not invited to this party 😭

:*perl*::sub-entry {
    printf("%s::%s entered at %s line %d\n",
          copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2);
}

sub-return(SUBNAME, FILE, LINE, PACKAGE)

Traces the exit of any subroutine. same deal as above: all of the variables refer to the subroutine that is returning, and there is currently no way to get ahold of any information about the subroutine's caller from a DTrace action.

:*perl*::sub-return {
    printf("%s::%s returned at %s line %d\n",
          copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2);
}

phase-change(NEWPHASE, OLDPHASE)

Traces changes to Perl's interpreter state. you can lowkey internalize this as tracing changes to Perl's ${^GLOBAL_PHASE} variable β€” especially since the values for NEWPHASE and OLDPHASE are literally the strings that ${^GLOBAL_PHASE} reports. consistent, we love to see it. 🫢

:*perl*::phase-change {
    printf("Phase changed from %s to %s\n",
        copyinstr(arg1), copyinstr(arg0));
}

op-entry(OPNAME)

Traces the execution of each opcode in the Perl runloop. this probe fires before the opcode is executed. and when the Perl debugger is enabled, the DTrace probe is fired after the debugger hooks (but still before the opcode itself is executed). the timing, the precision, the drama. πŸ’œ

:*perl*::op-entry {
    printf("About to execute opcode %s\n", copyinstr(arg0));
}

loading-file(FILENAME)

Fires when Perl is about to load an individual file β€” whether that's from use, require, or do. it goes off before the file is read from disk. and btw the filename argument gets converted to local filesystem paths instead of giving you Module::Name-style names. so like, actual paths, not vibes.

:*perl*:loading-file {
    printf("About to load %s\n", copyinstr(arg0));
}

loaded-file(FILENAME)

Fires when Perl has successfully loaded an individual file β€” again, whether from use, require, or do. this one fires after the file is read from disk and its contents evaluated. and same as its sibling, the filename argument is converted to local filesystem paths instead of Module::Name-style names. πŸŽ€

:*perl*:loaded-file {
    printf("Successfully loaded %s\n", copyinstr(arg0));
}

πŸ’… EXAMPLES πŸ’…

ok these are the iconic ones, let's go:

Most frequently called functions

# dtrace -qZn 'sub-entry { @[strjoin(strjoin(copyinstr(arg3),"::"),copyinstr(arg0))] = count() } END {trunc(@, 10)}'

Class::MOP::Attribute::slots                                    400
Try::Tiny::catch                                                411
Try::Tiny::try                                                  411
Class::MOP::Instance::inline_slot_access                        451
Class::MOP::Class::Immutable::Trait:::around                    472
Class::MOP::Mixin::AttributeCore::has_initializer               496
Class::MOP::Method::Wrapped::__ANON__                           544
Class::MOP::Package::_package_stash                             737
Class::MOP::Class::initialize                                  1128
Class::MOP::get_metaclass_by_name                              1204

Trace function calls

# dtrace -qFZn 'sub-entry, sub-return { trace(copyinstr(arg0)) }'

0  -> Perl_pp_entersub                        BEGIN
0  <- Perl_pp_leavesub                        BEGIN
0  -> Perl_pp_entersub                        BEGIN
0    -> Perl_pp_entersub                      import
0    <- Perl_pp_leavesub                      import
0  <- Perl_pp_leavesub                        BEGIN
0  -> Perl_pp_entersub                        BEGIN
0    -> Perl_pp_entersub                      dress
0    <- Perl_pp_leavesub                      dress
0    -> Perl_pp_entersub                      dirty
0    <- Perl_pp_leavesub                      dirty
0    -> Perl_pp_entersub                      whiten
0    <- Perl_pp_leavesub                      whiten
0  <- Perl_dounwind                           BEGIN

Function calls during interpreter cleanup

# dtrace -Zn 'phase-change /copyinstr(arg0) == "END"/ { self->ending = 1 } sub-entry /self->ending/ { trace(copyinstr(arg0)) }'

CPU     ID                    FUNCTION:NAME
  1  77214       Perl_pp_entersub:sub-entry   END
  1  77214       Perl_pp_entersub:sub-entry   END
  1  77214       Perl_pp_entersub:sub-entry   cleanup
  1  77214       Perl_pp_entersub:sub-entry   _force_writable
  1  77214       Perl_pp_entersub:sub-entry   _force_writable

System calls at compile time

# dtrace -qZn 'phase-change /copyinstr(arg0) == "START"/ { self->interesting = 1 } phase-change /copyinstr(arg0) == "RUN"/ { self->interesting = 0 } syscall::: /self->interesting/ { @[probefunc] = count() } END { trunc(@, 3) }'

lseek                                                           310
read                                                            374
stat64                                                         1056

Perl functions that execute the most opcodes

# dtrace -qZn 'sub-entry { self->fqn = strjoin(copyinstr(arg3), strjoin("::", copyinstr(arg0))) } op-entry /self->fqn != ""/ { @[self->fqn] = count() } END { trunc(@, 3) }'

warnings::unimport                                             4589
Exporter::Heavy::_rebuild_cache                                5039
Exporter::import                                              14578

πŸ“š REFERENCES πŸ“š


🧚 SEE ALSO 🧚

  • Devel::DTrace::Provider
    • This CPAN module lets you create application-level DTrace probes written in Perl. iykyk, it's giving very useful.

πŸ’œ AUTHORS πŸ’œ

Shawn M Moore sartak@gmail.com


and that's the whole page bestie!! 🌟 this was perl v5.44.0, dated 2026-10-17, and you can find it filed under PERLDTRACE(1perl). go trace something iconic, ily πŸ«Άβœ¨πŸ’–

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms