Home / Alt manpages / perldebug(1)

  • perldebug(1)
  • User command
  • linux

Debug a Perl Script from the Shell with perldebug

You will finish with a repeatable way to pause a Perl program, inspect its values and call stack, step over or into code, set a breakpoint, and continue or quit from the terminal. The examples match Perl 5.38.2 and the perldebug(1) manual installed with the perl-doc package.

Allow about fifteen minutes. You need Perl, a script you can run safely, and a terminal. No elevated privileges are needed. The debugger executes Perl expressions you type, so do not paste untrusted commands into its prompt.

1. Check the installed debugger

Confirm the interpreter and documentation version before relying on an option. This is an ordinary read-only check:

$ perl -v
This is perl 5, version 38, subversion 2 (v5.38.2)

$ man perldebug

The debugger is part of Perl. The -d switch tells Perl to compile the program with debugging information and load its debugger library. It is not a separate debugger binary, and the program still has to compile successfully.

Checkpoint

If perl -v works but man perldebug does not, you have the interpreter but may be missing the perl-doc package. The debugger itself can still run, but use the installed manual or package documentation for the exact command set.

2. Start with a harmless script

Use a small copy or a test program while learning. For example, save this as debug-example.pl:

use strict;
use warnings;

sub total {
    my ($left, $right) = @_;
    return $left + $right;
}

my $answer = total(2, 3);
print "answer=$answer\n";

Run it normally first. That separates a program error from a debugger error:

$ perl debug-example.pl
answer=5

Now start the debugger:

$ perl -d debug-example.pl

Loading DB routines from perl5db.pl version 1.77
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(debug-example.pl:3):
3:    sub total {

The exact file path and prompt number vary. Perl stops before the first run-time executable statement, and the displayed line is the one about to execute. Compile-time work such as most use statements is not stopped in the same way.

3. Inspect code and values

At the DB<1> prompt, use l to list source around the current line. Use p for a simple expression and x for a recursive, formatted dump:

DB<1> l
DB<2> p $answer
DB<3> x \@items

The prompt number is a history number, not a source line. The p command prints an expression through the debugger output handle. The x command evaluates in list context and is usually clearer for arrays, hashes and nested references. If a value has not been assigned yet, an empty or undefined result can be correct: step to the assignment before inspecting it.

For a stack view, enter T. It reports the current subroutine and its callers. This is often the quickest way to establish how execution reached the failing line:

DB<4> T
$ = main::total called from file 'debug-example.pl' line 8
$ = main:: called from file 'debug-example.pl' line 9

File names, line numbers and argument details depend on the program. The left-hand context marker can be $, @ or .; it describes scalar, list or void context.

4. Move through execution

Use one command at a time so the state stays easy to follow:

  • s steps to the next statement and descends into a subroutine call.
  • n steps to the next statement but runs over subroutine calls.
  • r continues until the current subroutine returns.
  • c continues execution until the next breakpoint or program exit.

After stepping over the call, inspect the result:

DB<5> n
DB<6> p $answer
5
DB<7> c
answer=5
Debugged program terminated.  Use q to quit or R to restart

The prompt may stop again at a different line, and the termination message may include more advice. Pressing Enter repeats the last n or s command. That is convenient, but it is also an easy way to step farther than intended, so check the displayed source line after a few repeats.

5. Set a breakpoint for a real failure

Restart the debugger or launch it again, then set a breakpoint by source line with b LINE, or by subroutine with b SUBNAME. For the sample, stop at the return:

$ perl -d debug-example.pl
DB<1> b 5
DB<2> c
DB<3> p $left
2
DB<4> p $right
3

A line breakpoint must be on a breakable statement in the current file. If it does not stop, use l to check the source line and L to list breakpoints, actions and watch expressions. A conditional breakpoint is also available with the documented b LINE CONDITION form, but keep the condition simple enough to explain when it fires.

Breakpoints and debugger options affect this debugging session. They do not edit the Perl file or persist as program configuration. Quit with q when finished. If the program has changed state outside the process, such as writing a file or sending a request, the debugger cannot undo that side effect. Test with safe inputs before stepping through production jobs.

6. Handle the traps

Commands the debugger does not recognise are evaluated as Perl in the current package. That makes the prompt useful for a quick calculation, but it also means a typo can run code. If a function name in your program collides with a debugger command, prefix the call with a semicolon, plus sign, parentheses or braces so it is treated as Perl.

Lexical variables created or changed in a one-off prompt evaluation do not survive the evaluation's implicit scope. Put related declarations and use on one line if you are experimenting, or inspect the program's real lexical state with y when the PadWalker module version 0.08 or newer is available.

For a non-interactive trace, set PERLDB_OPTS for one command:

$ PERLDB_OPTS='NonStop frame=2' perl -d debug-example.pl
answer=5

This runs without waiting for debugger input and prints call entry and exit information. Treat PERLDB_OPTS as temporary shell state. Do not put it in a shared service environment until you have checked the output volume and destination.

Compile-time code needs separate attention. BEGIN, UNITCHECK, CHECK and use statements are not normally stopped by the debugger. A program can explicitly request a stop with $DB::single = 1, but adding that line changes the program and should be removed after the investigation.

Done means

  • perl -d starts the installed source debugger for your script.
  • You can list source, inspect simple and nested values, and read a stack trace.
  • You know when to use s, n, r and c.
  • You can set and inspect a breakpoint without editing persistent configuration.
  • You distinguish run-time stops from compile-time execution.
  • You quit safely and have considered side effects before debugging a real job.