| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# Derived from perl5db.pl |
|
2
|
|
|
|
|
|
|
# Tracks calls and returns and stores some stack frame |
|
3
|
|
|
|
|
|
|
# information. |
|
4
|
|
|
|
|
|
|
package DB; |
|
5
|
12
|
|
|
12
|
|
83
|
use warnings; no warnings 'redefine'; use utf8; |
|
|
12
|
|
|
12
|
|
140
|
|
|
|
12
|
|
|
12
|
|
380
|
|
|
|
12
|
|
|
|
|
63
|
|
|
|
12
|
|
|
|
|
28
|
|
|
|
12
|
|
|
|
|
325
|
|
|
|
12
|
|
|
|
|
712
|
|
|
|
12
|
|
|
|
|
40
|
|
|
|
12
|
|
|
|
|
118
|
|
|
6
|
12
|
|
|
12
|
|
310
|
no warnings 'once'; |
|
|
12
|
|
|
|
|
27
|
|
|
|
12
|
|
|
|
|
368
|
|
|
7
|
12
|
|
|
12
|
|
629
|
use English qw( -no_match_vars ); |
|
|
12
|
|
|
|
|
3062
|
|
|
|
12
|
|
|
|
|
97
|
|
|
8
|
12
|
|
|
12
|
|
4284
|
use version; |
|
|
12
|
|
|
|
|
1507
|
|
|
|
12
|
|
|
|
|
189
|
|
|
9
|
12
|
|
|
12
|
|
848
|
use B; |
|
|
12
|
|
|
|
|
32
|
|
|
|
12
|
|
|
|
|
587
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
12
|
|
|
12
|
|
78
|
use constant SINGLE_STEPPING_EVENT => 1; |
|
|
12
|
|
|
|
|
26
|
|
|
|
12
|
|
|
|
|
752
|
|
|
12
|
12
|
|
|
12
|
|
77
|
use constant NEXT_STEPPING_EVENT => 2; |
|
|
12
|
|
|
|
|
31
|
|
|
|
12
|
|
|
|
|
563
|
|
|
13
|
12
|
|
|
12
|
|
78
|
use constant DEEP_RECURSION_EVENT => 4; |
|
|
12
|
|
|
|
|
35
|
|
|
|
12
|
|
|
|
|
698
|
|
|
14
|
12
|
|
|
12
|
|
75
|
use constant RETURN_EVENT => 32; |
|
|
12
|
|
|
|
|
34
|
|
|
|
12
|
|
|
|
|
714
|
|
|
15
|
12
|
|
|
12
|
|
70
|
use constant CALL_EVENT => 64; |
|
|
12
|
|
|
|
|
27
|
|
|
|
12
|
|
|
|
|
540
|
|
|
16
|
|
|
|
|
|
|
|
|
17
|
12
|
|
|
12
|
|
71
|
use vars qw($return_value @return_value @ret $ret @stack %fn_brkpt $deep); |
|
|
12
|
|
|
|
|
30
|
|
|
|
12
|
|
|
|
|
1448
|
|
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
BEGIN { |
|
20
|
12
|
|
|
12
|
|
55
|
@DB::ret = (); # return value of last sub executed in list context |
|
21
|
12
|
|
|
|
|
34
|
$DB::ret = ''; # return value of last sub executed in scalar context |
|
22
|
12
|
|
|
|
|
28
|
$DB::return_type = 'undef'; |
|
23
|
12
|
|
|
|
|
77
|
%DB::fn_brkpt = (); |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# $deep: Maximium stack depth before we complain. |
|
26
|
|
|
|
|
|
|
# See RT #117407 |
|
27
|
|
|
|
|
|
|
# https://rt.perl.org/rt3//Public/Bug/Display.html?id=117407 |
|
28
|
|
|
|
|
|
|
# for justification for why this should be 1000 rather than something |
|
29
|
|
|
|
|
|
|
# smaller. |
|
30
|
12
|
|
|
|
|
29
|
$DB::deep = 500; |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# $stack_depth is to track the current stack depth using the |
|
33
|
|
|
|
|
|
|
# auto-stacked-variable trick. It is 'local'ized repeatedly as |
|
34
|
|
|
|
|
|
|
# a simple way to keep track of #stack. |
|
35
|
12
|
|
|
|
|
39
|
$DB::stack_depth = 0; |
|
36
|
12
|
|
|
|
|
1552
|
@DB::stack = (0); # Per-frame debugger flags |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub subcall_debugger { |
|
40
|
0
|
0
|
0
|
0
|
0
|
|
if ($DB::single || $DB::signal) { |
|
41
|
0
|
0
|
|
|
|
|
_warnall($#DB::stack . " levels deep in subroutine calls.\n") if $DB::single & 4; |
|
42
|
0
|
|
|
|
|
|
local $DB::event = 'call'; |
|
43
|
0
|
|
|
|
|
|
$DB::single = 0; |
|
44
|
0
|
|
|
|
|
|
$DB::signal = 0; |
|
45
|
0
|
|
|
|
|
|
$DB::running = 0; |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# lock the debugger and get the thread id for the prompt |
|
48
|
0
|
0
|
|
|
|
|
if ($ENV{PERL5DB_THREADED}) { |
|
49
|
0
|
|
|
|
|
|
require threads; |
|
50
|
0
|
|
|
|
|
|
require threads::shared; |
|
51
|
0
|
|
|
|
|
|
import threads::shared qw(share); |
|
52
|
12
|
|
|
12
|
|
87
|
no strict; no warnings; |
|
|
12
|
|
|
12
|
|
24
|
|
|
|
12
|
|
|
|
|
310
|
|
|
|
12
|
|
|
|
|
69
|
|
|
|
12
|
|
|
|
|
28
|
|
|
|
12
|
|
|
|
|
11002
|
|
|
53
|
0
|
|
|
|
|
|
lock($DBGR); |
|
54
|
0
|
|
|
|
|
|
$tid = eval { "[".threads->tid."]" }; |
|
|
0
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
|
|
57
|
0
|
|
|
|
|
|
local $OP_addr = Devel::Callsite::callsite(1); |
|
58
|
|
|
|
|
|
|
|
|
59
|
0
|
|
|
|
|
|
$DB::subroutine = $sub; |
|
60
|
0
|
|
|
|
|
|
my $entry = $DB::sub{$sub}; |
|
61
|
0
|
0
|
|
|
|
|
if ($entry =~ /^(.*)\:(\d+)-(\d+)$/) { |
|
62
|
0
|
|
|
|
|
|
$DB::filename = $1; |
|
63
|
0
|
|
|
|
|
|
$DB::lineno = $2; |
|
64
|
0
|
|
|
|
|
|
$DB::caller = [ |
|
65
|
|
|
|
|
|
|
$DB::filename, $DB::lineno, $DB::subroutine, |
|
66
|
|
|
|
|
|
|
0 != scalar(@_), $DB::wantarray |
|
67
|
|
|
|
|
|
|
]; |
|
68
|
|
|
|
|
|
|
} |
|
69
|
0
|
|
|
|
|
|
for my $c (@clients) { |
|
70
|
|
|
|
|
|
|
# Now sit in an event loop until something sets $running |
|
71
|
0
|
|
|
|
|
|
my $after_eval = 0; |
|
72
|
0
|
|
|
|
|
|
do { |
|
73
|
|
|
|
|
|
|
# Show display expresions |
|
74
|
0
|
|
|
|
|
|
my $display_aref = $c->display_lists; |
|
75
|
0
|
|
|
|
|
|
for my $disp (@$display_aref) { |
|
76
|
0
|
0
|
0
|
|
|
|
next unless $disp && $disp->enabled; |
|
77
|
0
|
|
|
|
|
|
my $opts = {return_type => $disp->return_type, |
|
78
|
|
|
|
|
|
|
namespace_package => $namespace_package, |
|
79
|
|
|
|
|
|
|
fix_file_and_line => 1, |
|
80
|
|
|
|
|
|
|
hide_position => 0}; |
|
81
|
|
|
|
|
|
|
# FIXME: allow more than just scalar contexts. |
|
82
|
0
|
|
|
|
|
|
&DB::save_vars(); |
|
83
|
0
|
|
|
|
|
|
my $eval_result = |
|
84
|
|
|
|
|
|
|
&DB::eval_with_return($disp->arg, $opts, @DB::saved); |
|
85
|
0
|
|
|
|
|
|
my $mess; |
|
86
|
0
|
0
|
|
|
|
|
if (defined($eval_result)) { |
|
87
|
0
|
|
|
|
|
|
$mess = sprintf("%d: $eval_result", $disp->number); |
|
88
|
|
|
|
|
|
|
} else { |
|
89
|
0
|
|
|
|
|
|
$mess = sprintf("%d: undef", $disp->number); |
|
90
|
|
|
|
|
|
|
} |
|
91
|
0
|
|
|
|
|
|
$c->output($mess); |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
0
|
0
|
|
|
|
|
if (1 == $after_eval ) { |
|
|
|
0
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
$event = 'after_eval'; |
|
96
|
|
|
|
|
|
|
} elsif (2 == $after_eval) { |
|
97
|
0
|
|
|
|
|
|
$event = 'after_nest' |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# call client event loop; must not block |
|
101
|
0
|
|
|
|
|
|
$c->idle($event, $watch_triggered); |
|
102
|
0
|
|
|
|
|
|
$after_eval = 0; |
|
103
|
0
|
0
|
0
|
|
|
|
if ($running == 2 && defined($eval_str)) { |
|
104
|
|
|
|
|
|
|
# client wants something eval-ed |
|
105
|
|
|
|
|
|
|
# FIXME: turn into subroutine. |
|
106
|
|
|
|
|
|
|
|
|
107
|
0
|
|
|
|
|
|
local $nest = $eval_opts->{nest}; |
|
108
|
0
|
|
|
|
|
|
my $return_type = $eval_opts->{return_type}; |
|
109
|
0
|
0
|
|
|
|
|
$return_type = '' unless defined $return_type; |
|
110
|
0
|
|
|
|
|
|
my $opts = $eval_opts; |
|
111
|
0
|
|
|
|
|
|
$opts->{namespace_package} = $namespace_package; |
|
112
|
|
|
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
&DB::save_vars(); |
|
114
|
0
|
0
|
|
|
|
|
if ('@' eq $return_type) { |
|
|
|
0
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
|
&DB::eval_with_return($eval_str, $opts, @DB::saved); |
|
116
|
|
|
|
|
|
|
} elsif ('%' eq $return_type) { |
|
117
|
0
|
|
|
|
|
|
&DB::eval_with_return($eval_str, $opts, @DB::saved); |
|
118
|
|
|
|
|
|
|
} else { |
|
119
|
0
|
|
|
|
|
|
$eval_result = |
|
120
|
|
|
|
|
|
|
&DB::eval_with_return($eval_str, $opts, @DB::saved); |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
|
|
123
|
0
|
0
|
|
|
|
|
if ($nest) { |
|
124
|
0
|
|
|
|
|
|
$DB::in_debugger = 1; |
|
125
|
0
|
|
|
|
|
|
$after_eval = 2; |
|
126
|
|
|
|
|
|
|
} else { |
|
127
|
0
|
|
|
|
|
|
$after_eval = 1; |
|
128
|
|
|
|
|
|
|
} |
|
129
|
0
|
|
|
|
|
|
$running = 0; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
} until $running; |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub check_for_stop() |
|
137
|
|
|
|
|
|
|
{ |
|
138
|
0
|
|
|
0
|
0
|
|
my $brkpts = $DB::fn_brkpt{$sub}; |
|
139
|
0
|
0
|
|
|
|
|
if ($brkpts) { |
|
140
|
0
|
|
|
|
|
|
my @action = (); |
|
141
|
0
|
|
|
|
|
|
for (my $i=0; $i < @$brkpts; $i++) { |
|
142
|
0
|
|
|
|
|
|
my $brkpt = $brkpts->[$i]; |
|
143
|
0
|
0
|
|
|
|
|
next unless defined $brkpt; |
|
144
|
0
|
0
|
|
|
|
|
if ($brkpt->type eq 'action') { |
|
145
|
0
|
|
|
|
|
|
push @action, $brkpt; |
|
146
|
0
|
|
|
|
|
|
next ; |
|
147
|
|
|
|
|
|
|
} |
|
148
|
0
|
|
|
|
|
|
$stop = 0; |
|
149
|
0
|
0
|
|
|
|
|
if ($brkpt->condition eq '1') { |
|
150
|
|
|
|
|
|
|
# A cheap and simple test for unconditional. |
|
151
|
0
|
|
|
|
|
|
$stop = 1; |
|
152
|
|
|
|
|
|
|
} else { |
|
153
|
0
|
|
|
|
|
|
my $eval_str = sprintf("\$DB::stop = do { %s; }", |
|
154
|
|
|
|
|
|
|
$brkpt->condition); |
|
155
|
0
|
|
|
|
|
|
my $opts = {return_type => ';', # ignore return |
|
156
|
|
|
|
|
|
|
namespace_package => $namespace_package, |
|
157
|
|
|
|
|
|
|
fix_file_and_line => 1, |
|
158
|
|
|
|
|
|
|
hide_position => 0}; |
|
159
|
0
|
|
|
|
|
|
&DB::save_vars(); |
|
160
|
0
|
|
|
|
|
|
&DB::eval_with_return($eval_str, $opts, @DB::saved); |
|
161
|
|
|
|
|
|
|
} |
|
162
|
0
|
0
|
0
|
|
|
|
if ($stop && $brkpt->enabled && !($DB::single & RETURN_EVENT)) { |
|
|
|
|
0
|
|
|
|
|
|
163
|
0
|
|
|
|
|
|
$DB::brkpt = $brkpt; |
|
164
|
0
|
|
|
|
|
|
$event = $brkpt->type; |
|
165
|
0
|
0
|
|
|
|
|
if ($event eq 'tbrkpt') { |
|
166
|
|
|
|
|
|
|
# breakpoint is temporary and remove it. |
|
167
|
0
|
|
|
|
|
|
undef $brkpts->[$i]; |
|
168
|
|
|
|
|
|
|
} else { |
|
169
|
0
|
|
|
|
|
|
my $hits = $brkpt->hits + 1; |
|
170
|
0
|
|
|
|
|
|
$brkpt->hits($hits); |
|
171
|
|
|
|
|
|
|
} |
|
172
|
0
|
|
|
|
|
|
$DB::single = 1; |
|
173
|
0
|
|
|
|
|
|
$DB::wantarray = wantarray; |
|
174
|
0
|
|
|
|
|
|
local $OP_addr = Devel::Callsite::callsite(1); |
|
175
|
0
|
|
|
|
|
|
&subcall_debugger() ; |
|
176
|
0
|
|
|
|
|
|
last; |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
} |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# Push the $DB:single onto @DB::stack and set $DB_single. |
|
183
|
|
|
|
|
|
|
sub push_DB_single_and_set() |
|
184
|
|
|
|
|
|
|
{ |
|
185
|
|
|
|
|
|
|
# Expand @stack. |
|
186
|
0
|
|
|
0
|
0
|
|
$#DB::stack = $DB::stack_depth; |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# Save current single-step setting. |
|
189
|
0
|
|
|
|
|
|
$DB::stack[-1] = $DB::single; |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# printf "++ \$DB::single for $sub: 0%x\n", $DB::single if $DB::single; |
|
192
|
|
|
|
|
|
|
# Turn off all flags except single-stepping or return event. |
|
193
|
0
|
|
|
|
|
|
$DB::single &= SINGLE_STEPPING_EVENT; |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# If we've gotten really deeply recursed, turn on the flag that will |
|
196
|
|
|
|
|
|
|
# make us stop with the 'deep recursion' message. |
|
197
|
0
|
0
|
|
|
|
|
$DB::single |= DEEP_RECURSION_EVENT if $#stack == $deep; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
#### |
|
202
|
|
|
|
|
|
|
# When debugging is enabled, this routine gets called instead of |
|
203
|
|
|
|
|
|
|
# the orignal subroutine. $DB::sub contains the intended subroutine |
|
204
|
|
|
|
|
|
|
# to be called. Thus, this routine must run &$DB::sub |
|
205
|
|
|
|
|
|
|
# in order to get the original routine called. The fact that |
|
206
|
|
|
|
|
|
|
# this routine is called instead allows us to wrap or put code |
|
207
|
|
|
|
|
|
|
# around subroutine calls |
|
208
|
|
|
|
|
|
|
# |
|
209
|
|
|
|
|
|
|
sub DB::sub { |
|
210
|
|
|
|
|
|
|
# Do not use a regex in this subroutine -> results in corrupted |
|
211
|
|
|
|
|
|
|
# memory See: [perl #66110] |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# lock ourselves under threads |
|
214
|
0
|
0
|
|
0
|
1
|
|
lock($DBGR) if $ENV{PERL5DB_THREADED}; |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# Whether or not the autoloader was running, a scalar to put the |
|
217
|
|
|
|
|
|
|
# sub's return value in (if needed), and an array to put the sub's |
|
218
|
|
|
|
|
|
|
# return value in (if needed). |
|
219
|
0
|
|
|
|
|
|
my ( $al, $ret, @ret ) = ""; |
|
220
|
0
|
0
|
0
|
|
|
|
if ($DB::sub eq 'threads::new' && $ENV{PERL5DB_THREADED}) { |
|
221
|
0
|
|
|
|
|
|
print "creating new thread\n"; |
|
222
|
|
|
|
|
|
|
} |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
# If the last ten characters are '::AUTOLOAD', note we've traced |
|
225
|
|
|
|
|
|
|
# into AUTOLOAD for $DB::sub. |
|
226
|
0
|
0
|
0
|
|
|
|
if ( length($DB::sub) > 10 && substr( $DB::sub, -10, 10 ) eq '::AUTOLOAD' ) { |
|
227
|
12
|
|
|
12
|
|
99
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
27
|
|
|
|
12
|
|
|
|
|
2014
|
|
|
228
|
0
|
0
|
|
|
|
|
$al = " for $$DB::sub" if defined $$DB::sub; |
|
229
|
|
|
|
|
|
|
} |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# We stack the stack pointer and then increment it to protect us |
|
232
|
|
|
|
|
|
|
# from a situation that might unwind a whole bunch of call frames |
|
233
|
|
|
|
|
|
|
# at once. Localizing the stack pointer means that it will automatically |
|
234
|
|
|
|
|
|
|
# unwind the same amount when multiple stack frames are unwound. |
|
235
|
0
|
|
|
|
|
|
local $stack_depth = $stack_depth + 1; # Protect from non-local exits |
|
236
|
0
|
|
|
|
|
|
push_DB_single_and_set(); |
|
237
|
|
|
|
|
|
|
|
|
238
|
0
|
0
|
0
|
|
|
|
if (defined($DB::running) && $DB::running == 1) { |
|
239
|
0
|
|
|
|
|
|
local @DB::_ = @_; |
|
240
|
0
|
|
|
|
|
|
local(*DB::dbline) = "::_<$DB::filename"; |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# FIXME: this isn't quite right; |
|
243
|
0
|
|
|
|
|
|
$DB::addr = +B::svref_2object(\$DB::subroutine); |
|
244
|
|
|
|
|
|
|
|
|
245
|
0
|
|
|
|
|
|
check_for_stop(); |
|
246
|
|
|
|
|
|
|
} |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# FIXME: this isn't quite right. For mysterious reasons $DB::wantarray |
|
249
|
|
|
|
|
|
|
# is tracking the wrong frame and is always @ |
|
250
|
|
|
|
|
|
|
# $DB::wantarray = $DB::wantarray ? '@' : ( defined $wantarray ? '$' : '.' ); |
|
251
|
0
|
|
|
|
|
|
$DB::wantarray = '?'; |
|
252
|
|
|
|
|
|
|
|
|
253
|
0
|
0
|
0
|
|
|
|
if ($DB::sub eq 'DESTROY' or |
|
|
|
0
|
0
|
|
|
|
|
|
254
|
|
|
|
|
|
|
substr($DB::sub, -9) eq '::DESTROY' or not defined wantarray) { |
|
255
|
0
|
|
|
|
|
|
&$DB::sub; |
|
256
|
12
|
|
|
12
|
|
83
|
no warnings 'uninitialized'; |
|
|
12
|
|
|
|
|
31
|
|
|
|
12
|
|
|
|
|
672
|
|
|
257
|
0
|
|
|
|
|
|
$DB::single |= pop(@stack); |
|
258
|
0
|
|
|
|
|
|
$DB::ret = undef; |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
elsif (wantarray) { |
|
261
|
|
|
|
|
|
|
# Called in array context. call sub and capture output. |
|
262
|
|
|
|
|
|
|
# DB::DB will recursively get control again if appropriate; |
|
263
|
|
|
|
|
|
|
# we'll come back here when the sub is finished. |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
{ |
|
266
|
12
|
|
|
12
|
|
69
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
27
|
|
|
|
12
|
|
|
|
|
1264
|
|
|
|
0
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# call the original subroutine and save the array value. |
|
268
|
0
|
|
|
|
|
|
@ret = &$DB::sub; |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# Pop the single-step value back off the stack. |
|
272
|
0
|
0
|
|
|
|
|
if ($stack[$stack_depth]) { |
|
273
|
0
|
|
|
|
|
|
$DB::single |= $stack[ $stack_depth-- ]; |
|
274
|
0
|
0
|
|
|
|
|
if ($single & RETURN_EVENT) { |
|
275
|
0
|
|
|
|
|
|
$DB::return_type = 'array'; |
|
276
|
0
|
|
|
|
|
|
@DB::return_value = @ret; |
|
277
|
0
|
|
|
|
|
|
DB::DB($DB::sub) ; |
|
278
|
0
|
|
|
|
|
|
return @DB::return_value; |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
} |
|
281
|
0
|
|
|
|
|
|
@ret; |
|
282
|
|
|
|
|
|
|
} else { |
|
283
|
|
|
|
|
|
|
# Called in array context. call sub and capture output. |
|
284
|
|
|
|
|
|
|
# DB::DB will recursively get control again if appropriate; |
|
285
|
|
|
|
|
|
|
# we'll come back here when the sub is finished. |
|
286
|
|
|
|
|
|
|
|
|
287
|
0
|
0
|
|
|
|
|
if ( defined wantarray ) { |
|
288
|
12
|
|
|
12
|
|
118
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
30
|
|
|
|
12
|
|
|
|
|
472
|
|
|
289
|
|
|
|
|
|
|
# call the original subroutine and save the array value. |
|
290
|
0
|
|
|
|
|
|
$ret = &$DB::sub; |
|
291
|
|
|
|
|
|
|
} else { |
|
292
|
12
|
|
|
12
|
|
82
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
30
|
|
|
|
12
|
|
|
|
|
3443
|
|
|
293
|
|
|
|
|
|
|
# Call the original lvalue sub and explicitly void the return |
|
294
|
|
|
|
|
|
|
# value. |
|
295
|
0
|
|
|
|
|
|
&$DB::sub; |
|
296
|
0
|
|
|
|
|
|
undef $ret; |
|
297
|
|
|
|
|
|
|
} |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
# Pop the single-step value back off the stack. |
|
300
|
0
|
0
|
|
|
|
|
$DB::single |= $stack[ $stack_depth-- ] if $stack[$stack_depth]; |
|
301
|
0
|
0
|
|
|
|
|
if ($single & RETURN_EVENT) { |
|
302
|
0
|
0
|
|
|
|
|
$DB::return_type = defined $ret ? 'scalar' : 'undef'; |
|
303
|
0
|
|
|
|
|
|
$DB::return_value = $ret; |
|
304
|
0
|
|
|
|
|
|
DB::DB($DB::sub) ; |
|
305
|
0
|
|
|
|
|
|
return $DB::return_value; |
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
# Return the appropriate scalar value. |
|
309
|
0
|
|
|
|
|
|
return $ret; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
} |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
#### |
|
314
|
|
|
|
|
|
|
# When debugging is enabled, this routine gets called instead of the |
|
315
|
|
|
|
|
|
|
# orignal subroutine in a left-hand (assignment) context. $DB::sub |
|
316
|
|
|
|
|
|
|
# contains the intended subroutine to be called. Thus, this routine |
|
317
|
|
|
|
|
|
|
# must run &$DB::sub in order to get the original routine called. The |
|
318
|
|
|
|
|
|
|
# fact that this routine is called instead allows us to wrap or |
|
319
|
|
|
|
|
|
|
# instrument code around subroutine calls. |
|
320
|
|
|
|
|
|
|
# |
|
321
|
|
|
|
|
|
|
sub DB::lsub : lvalue { |
|
322
|
|
|
|
|
|
|
# Possibly [perl #66110] also applies here as in sub. |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
# lock ourselves under threads |
|
325
|
0
|
0
|
|
0
|
0
|
|
lock($DBGR) if $ENV{PERL5DB_THREADED}; |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# Whether or not the autoloader was running, a scalar to put the |
|
328
|
|
|
|
|
|
|
# sub's return value in (if needed), and an array to put the sub's |
|
329
|
|
|
|
|
|
|
# return value in (if needed). |
|
330
|
0
|
|
|
|
|
|
my ( $al, $ret, @ret ) = ""; |
|
331
|
0
|
0
|
0
|
|
|
|
if ($DB::sub =~ /^threads::new$/ && $ENV{PERL5DB_THREADED}) { |
|
332
|
0
|
|
|
|
|
|
print "creating new thread\n"; |
|
333
|
|
|
|
|
|
|
} |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
# If the last ten characters are '::AUTOLOAD', note we've traced |
|
336
|
|
|
|
|
|
|
# into AUTOLOAD for $DB::sub. |
|
337
|
0
|
0
|
0
|
|
|
|
if ( length($DB::sub) > 10 && substr( $DB::sub, -10, 10 ) eq '::AUTOLOAD' ) { |
|
338
|
0
|
0
|
|
|
|
|
$al = " for $$DB::sub" if defined $$DB::sub;; |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
# We stack the stack pointer and then increment it to protect us |
|
342
|
|
|
|
|
|
|
# from a situation that might unwind a whole bunch of call frames |
|
343
|
|
|
|
|
|
|
# at once. Localizing the stack pointer means that it will automatically |
|
344
|
|
|
|
|
|
|
# unwind the same amount when multiple stack frames are unwound. |
|
345
|
0
|
|
|
|
|
|
local $stack_depth = $stack_depth + 1; # Protect from non-local exits |
|
346
|
0
|
|
|
|
|
|
push_DB_single_and_set(); |
|
347
|
|
|
|
|
|
|
|
|
348
|
0
|
|
|
|
|
|
local(*DB::dbline) = "::_<$DB::filename"; |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
# FIXME: this isn't quite right; |
|
351
|
0
|
|
|
|
|
|
$DB::addr = +B::svref_2object(\$DB::subroutine); |
|
352
|
|
|
|
|
|
|
|
|
353
|
0
|
|
|
|
|
|
check_for_stop(); |
|
354
|
|
|
|
|
|
|
|
|
355
|
0
|
0
|
|
|
|
|
if (wantarray) { |
|
356
|
|
|
|
|
|
|
# Called in array context. call sub and capture output. |
|
357
|
|
|
|
|
|
|
# DB::DB will recursively get control again if appropriate; we'll come |
|
358
|
|
|
|
|
|
|
# back here when the sub is finished. |
|
359
|
|
|
|
|
|
|
{ |
|
360
|
12
|
|
|
12
|
|
85
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
30
|
|
|
|
12
|
|
|
|
|
1000
|
|
|
|
0
|
|
|
|
|
|
|
|
361
|
0
|
|
|
|
|
|
@ret = &$DB::sub; |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
# Pop the single-step value back off the stack. |
|
365
|
0
|
|
|
|
|
|
$DB::single |= $stack[ $stack_depth-- ]; |
|
366
|
0
|
0
|
|
|
|
|
if ($DB::single & RETURN_EVENT) { |
|
367
|
0
|
|
|
|
|
|
$DB::return_type = 'array'; |
|
368
|
0
|
|
|
|
|
|
@DB::return_value = @ret; |
|
369
|
0
|
|
|
|
|
|
DB::DB($DB::sub) ; |
|
370
|
0
|
|
|
|
|
|
return @DB::return_value; |
|
371
|
|
|
|
|
|
|
} |
|
372
|
0
|
|
|
|
|
|
@ret; |
|
373
|
|
|
|
|
|
|
} else { |
|
374
|
|
|
|
|
|
|
# Called in array context. call sub and capture output. |
|
375
|
|
|
|
|
|
|
# DB::DB will recursively get control again if appropriate; |
|
376
|
|
|
|
|
|
|
# we'll come back here when the sub is finished. |
|
377
|
|
|
|
|
|
|
|
|
378
|
0
|
0
|
|
|
|
|
if ( defined wantarray ) { |
|
379
|
12
|
|
|
12
|
|
69
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
29
|
|
|
|
12
|
|
|
|
|
402
|
|
|
380
|
|
|
|
|
|
|
# Save the value if it's wanted at all. |
|
381
|
0
|
|
|
|
|
|
$ret = &$DB::sub; |
|
382
|
|
|
|
|
|
|
} else { |
|
383
|
12
|
|
|
12
|
|
69
|
no strict 'refs'; |
|
|
12
|
|
|
|
|
28
|
|
|
|
12
|
|
|
|
|
2906
|
|
|
384
|
|
|
|
|
|
|
# Void return, explicitly. |
|
385
|
0
|
|
|
|
|
|
&$DB::sub; |
|
386
|
0
|
|
|
|
|
|
undef $ret; |
|
387
|
|
|
|
|
|
|
} |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# Pop the single-step value back off the stack. |
|
390
|
0
|
0
|
|
|
|
|
$DB::single |= $stack[ $stack_depth-- ] if $stack[$stack_depth]; |
|
391
|
0
|
0
|
|
|
|
|
if ($DB::single & RETURN_EVENT) { |
|
392
|
0
|
0
|
|
|
|
|
$DB::return_type = defined $ret ? 'scalar' : 'undef'; |
|
393
|
0
|
|
|
|
|
|
$DB::return_value = $ret; |
|
394
|
0
|
|
|
|
|
|
DB::DB($DB::sub) ; |
|
395
|
0
|
|
|
|
|
|
return $DB::return_value; |
|
396
|
|
|
|
|
|
|
} |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
# Return the appropriate scalar value. |
|
399
|
0
|
|
|
|
|
|
return $ret; |
|
400
|
|
|
|
|
|
|
} |
|
401
|
|
|
|
|
|
|
} |
|
402
|
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
#### |
|
404
|
|
|
|
|
|
|
# without args: returns all defined subroutine names |
|
405
|
|
|
|
|
|
|
# with subname args: returns a listref [file, start, end] |
|
406
|
|
|
|
|
|
|
# |
|
407
|
|
|
|
|
|
|
sub subs { |
|
408
|
0
|
|
|
0
|
0
|
|
my $s = shift; |
|
409
|
0
|
0
|
|
|
|
|
if (@_) { |
|
410
|
0
|
|
|
|
|
|
my(@ret) = (); |
|
411
|
0
|
|
|
|
|
|
while (@_) { |
|
412
|
0
|
|
|
|
|
|
my $name = shift; |
|
413
|
0
|
0
|
|
|
|
|
next unless $name; |
|
414
|
|
|
|
|
|
|
push @ret, [$DB::sub{$name} =~ /^(.*)\:(\d+)-(\d+)$/] |
|
415
|
0
|
0
|
|
|
|
|
if exists $DB::sub{$name}; |
|
416
|
|
|
|
|
|
|
} |
|
417
|
0
|
|
|
|
|
|
return @ret; |
|
418
|
|
|
|
|
|
|
} |
|
419
|
0
|
|
|
|
|
|
return keys %DB::sub; |
|
420
|
|
|
|
|
|
|
} |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
1; |