Question

With the Perl debugger, I know I can set breakpoints at certain lines of code with the b command. Can I get the debugger to stop as soon as the contents of a variable has changed?

Was it helpful?

Solution

You can create watch points using the w command in the Perl debugger.

Crash course on the w debugger command:

Create a watch-expression by typing w and then an expression that will monitored for changes:

DB<1> w $variablename

Enter c to continue until the watched expression changes. Once you do, you will get output similar to this:

DB<2> c
Watchpoint 0:   $variablename changed:
    old value:  ''
    new value:  'hi'
main::(ex.pl:6):    $variablename = "";    

Note that the debugger stops at the statement after the changed has happened, so the line displayed might not be relevant at all.

Also note that the expression is stringified. So for example, changing a variable to undef will give you this output:

  DB<2> c
Watchpoint 0:   $variablename changed:
    old value:  'hi'
    new value:  ''
main::(ex.pl:7):    $variablename = undef;

If the variable is subsequently changed to an empty string, the debugger will not stop, as a stringified empty string and a stringified undef is considered equal.

If the watch expression is a list, the debugger will compare the stringified elements of the list:

  DB<1> w $variablename, "second"

  DB<2> c
Watchpoint 0:   $variablename, "second" changed:
    old value:  'one', 'second'
    new value:  'two', 'second'
main::(hi.pl:6):    $variablename = "three";

You can use array variables or hash variables as watch-expressions, and they will be treated as any other list.

To delete a watch-expression, use the W command, and to view a list of active watch-expressions, use the L command.

Tip: Use temporary global variables

Since the watch-expression is re-evaluated with every statement, you can't expect a watch-expression that uses a lexical variable to work out of scope. A quick tip is to create a global reference to the lexical, and track that instead:

DB<1> $main::my_debug_variable = $hashref_lexical_variable

DB<2> w $main::my_debug_variable->{key_im_watching}

Tip: Use Data::Dumper

Use Data::Dumper to watch the contents of a non-scalar:

DB<1> w Data::Dumper->Dump([$hashref])

This is preferable to a simple w $hashref, because it will stop when the values of the hash change, rather than simply the address the reference is pointing (since a hashref stringifies to something like HASH(0x2a07a90)).

OTHER TIPS

Additionally, you can use "ddd your_script.pl&" in the Linux, and watch variables like C/C++ debugger do in GUI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top