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; |