I have a case where a local variable in a sub
has the wrong un-blessed value after several invocations, and I'd like to break to the Perl debugger (when the program runs under debugger control, of course) if a specific condition is met.
I could try a conditional breakpoint interactively, but that would be a lot of typing work when repeating the "modify, debug" cycle many times.
Anyway I'd like to know whether its possible to use a construct like $DB::single=1 if (...);
.
When I tried it, it did not work, and the breakpoint was active all the time.
So is it possible?
What I had tried
Basically my problem is that the line @l_socks = @{$lsa->sockets()};
triggered a "Can't call "sockets" on unblessed reference at ...".
As the code is in a subroutine that is called many times before the problem happens, I added $DB::single = 1 unless (ref $lsa);
before the problematic line, but that did not work.
So maybe my problem is that $lsa
is not a scalar as expected, but a reference; unblesswd however.
CodePudding user response:
Yes, you can do that. It breaks at the next breakable line.
Consider the following program.
use strict;
use warnings;
print "hello";
for my $foo ( 1.. 10 ) {
print "$foo\n";
if ($foo == 9) {
$DB::single = 1;
}
}
There's a conditional breakpoint when $foo
is 9. The breakpoint gets set after the print
. It turns the breaks on, but it only stops at the next breakable line, which is the print
line for when $foo
is 10.
$ perl -d breaking.pl
Loading DB routines from perl5db.pl version 1.51
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(breaking.pl:4): print "hello";
DB<1> r
hello1
2
3
4
5
6
7
8
9
main::(breaking.pl:7): print "$foo\n";
DB<1> l
7==> print "$foo\n";
8: if ($foo == 9) {
9: $DB::single = 1;
10 }
11 }
12
DB<1> x $foo
0 10
DB<2> r
10
Debugged program terminated. Use q to quit or R to restart,
So you need to do your check at the top of whatever it is you want to inspect.
CodePudding user response:
For completeness, here is the "answer" to my question:
$DB::single = 1
correctly enables a debugger breakpoint after the instruction following the command if the condition to trigger it is correct.
In my case I used an incorrect condition that would never trigger, so it seemed the $DB::single = 1
was ignored.
Fixing the condition fixed the problem.
For the code example shown (you are not expected to understand the details; SocketArray
is a package written for this program), using
unless (UNIVERSAL::isa($lsa, 'SocketArray') {
$DB::single = 1;
1;
}
fixed it, and the debugger stopped at 1;
when it triggered.