1. Perl
  2. Debugger

Perl Debugger Guide

One of Perl's most useful tools is the debugger. You can use the debugger to traverse the script line by line to see what's inside a variable, or to set a breakpoint and stop at that position.

Debuggers are really useful, but some people don't even know if they're doing Perl. Once you learn the debugger, you can't let go of it when you test. It's a tool I want you to use more and more from the time you learned Perl. I tried to summarize the commands and techniques of such a debugger.

Debugging script

I have prepared a simple script for debugging. Save it as debug.pl. We will use this script to explain the debugger.

my $message = 'Hello';
my @nums = (1, 2, 3);
my %scores = (math => 80, english => 77);

my $twice = twice (5);

# breakpoint
$DB::single = 1;

for my $num (@nums) {
    
  # Conditional breakpoints
  if ($num == 2) {$DB::single = 1}
  print "$num\n";
}

sub twice {
  my $num = shift;
  
  return $num * 2;
}

Debugger startup

To start the debugger, start perl with the "-d" option.

perl -d debug.pl

When you start the debugger, it stops at the first line.

main::(a.pl: 4): my $message = 'Hello';

Use "q" to exit the debugger.

q

Use "h" to get help.

h

Let's remember the debugger commands in order.

1. Execution command

This section describes the commands for executing the Perl debugger.

n - One line execution

Use "n" to execute a script on a single line. Type "n" and then "Enter" to go to the next line.

If you execute "n" in the initial state, the following will be displayed and you can confirm that you are advancing one line.

main::(a.pl: 5): my @nums = (1, 2, 3);

Type "n", "Enter", "n", "Enter" to reach the end of the script and end the script.

Debugged program terminated. Use q to quit or R to restart,

You will be asked if you want to stop or restart debugging, but if you want to do a second debug, be sure to stop debugging with q.

Entering "n", "Enter", "n", and "Enter" is a bit tedious. Actually, you can advance the line with "n" "Enter" "Enter" "Enter". If "n" or "s" was entered immediately before, you can press "Enter" to repeat the previous command.

It is easy to remember that n is n of "next".

s - single step execution

Use "s" to run the script in a single step. The difference from "n" is that it traces the internal processing of the subroutine.

Encourage one line execution with "n" and advance the script to the line where the subroutine call is.

main::(a.pl: 8): my $twice = twice (5);

You can move to the processing inside the subroutine by executing "s" on this line.

main::twice (a.pl:21): my $num = shift;

c - Run to breakpoint or specified line

"c" is a command that executes up to a breakpoint or a specified line. c is the acronym for continue.

c 5

Is executed until just before the 5th line.

main::(a.pl: 5): my @nums = (1, 2, 3);

Then without giving any arguments

c

Will advance to the position next to the breakpoint in the sentence.

main::(a.pl: 13): for my $num (@nums) {
# breakpoint
$DB::single = 1;

Is a breakpoint that can be embedded in a script. If you want to see the contents of a variable, set a breakpoint around the line immediately before it, and it is very convenient because you can stop the execution there.

2. Display commands

This section describes display commands.

p - Display the contents of variable

You can display the contents of the variable with "p". For example, if you want to display a variable called $message, do as follows.

p $message

x - Expand and display the contents of variable

The "p" is useful for displaying the contents of a scalar variable, but not for displaying hashes, arrays, or even more complex data structures.

"x" can be used to display the internal structure of data in an easy-to-understand way. Note that you must pass a reference to the "x" argument.

For example, to display the contents of%scores:\Is for getting a reference.

x \%scores

The variable data is displayed in an easy-to-understand way as shown below.

0 HASH (0x19b205c)
   'english' => 77
   'math' => 80

3. Other frequently used commands

This section describes other frequently used commands.

v - Display surrounding lines

You can display the surrounding lines with "v".

v

If you execute "v" on the 4th line, the surrounding lines will be displayed as shown below.

1:use strict;
2:use warnings;
3
4 ==> my $message = 'Hello';
5: my @nums = (1, 2, 3);
6: my %scores = (math => 80, english => 77);

You can move the display to the line below by executing "v" many times.

. - Display current line

If you execute "v" many times, the display will move to the lower line. You can use "." To return to the current line at such times.

..

Arbitrary perl statement

The debugger can execute any Perl statement. Below is an example of using the defined function to see if a variable is defined.

print defined $message;

Any statement can be executed, which is useful for check.

4. Debugging techniques

Here are some commonly used debugging techniques.

Breakpoints in the text

Perl allows you to embed breakpoints in your scripts. If you assign 1 to a variable called single in the DB class (class for the debugger), the process will switch to single-step execution at that position.

$DB::single = 1;

This is really convenient, so please use it more and more. Also, don't forget to remove it from the script after you finish the exam.

Conditional breakpoints

When debugging, there are times when you want to stop processing and see the contents of variable only under certain conditions. In such a case, use conditional statement in combination with "$DB::single = 1". In this example, when $num is 2, the debugger stops at that position.

if ($num == 2) {$DB::single = 1}

Find out where the warning occurred

When testing scripts, I often get a warning that I am using an undefined value like the one below.

Use of uninitialized value

It is especially difficult to find the cause when a warning occurs in a loop such as for statement or while statement. This means that you should have assigned it somewhere, but you haven't been able to assign it, so you need to pinpoint its location.

I think most people will push the debugger to a position where it might be this place in such a case, but there is actually a way to catch the warning.

Perl can receive warnings as signals, so you can set the following breakpoints inside the block of the loop.

# Catch the warning and set a breakpoint
$SIG{__ WARN__} = sub {
    $DB::single = 1;
};

I can't use the history function because I can't use the up and down keys in the debugger.

I think there are cases where the history function cannot be used because the up and down keys cannot be used in the Perl debugger.This is because Term::ReadLine::Gnu is not installed.

The following C language libraries are required to install Term::ReadLine::Gnu.

For CentOS, RedHat

yum -y install readline-devel

Install Term::ReadLine::Gnu

Install Term::ReadLine::Gnu on cpanm or cpan.

# cpanm
cpanm Term::ReadLine::Gnu
# cpan
cpan Term::ReadLine::Gnu

Stop the debugger by specifying a breakpoint at any position

Perl's debugger is useful. When you start using a debugger, you will feel that you want to stop at the position you want to see. How can I stop at the position I want to see?

For example, when writing an exam, it is common to go through the same part of the same process multiple times. In such a case, the breakpoint description "$DB::single = 1" is not enough to stop it. In the following cases, the breakpoint will be caught when the first total is executed.

total (1, 2);

# I want to see only during this process
total (3, 4);

sub total {
  my ($num1, $num2) = @_;
  
  $DB::single = 1;
  my $total = $num1 + $num2;

  return $total;
}

Use conditional breakpoints in these cases.

total (1, 2);

# I want to see only during this process
$ENV{a} = 1;
total (3, 4);

sub total {
  my ($num1, $num2) = @_;
  
  $DB::single = 1 if $ENV{a};
  my $total = $num1 + $num2;

  return $total;
}

Environment variable are global variable, so let me use them for a moment. If you set the environment variable a and set a breakpoint only when it is set, you can stop at the position you want to stop. This is a pretty useful technique, so keep it in mind.

Please use the debugger positively

This concludes the explanation of debugger commands and techniques. There are many debugger commands, but if you write them here and remember only the ones, you will not have any trouble debugging. The debugger is a really useful tool, so please take advantage of it.

Related Informatrion