| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# Eval part of Perl's Core DB.pm library and perl5db.pl with modification. |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package DB; |
|
4
|
13
|
|
|
13
|
|
74182
|
use warnings; use strict; |
|
|
13
|
|
|
13
|
|
37
|
|
|
|
13
|
|
|
|
|
384
|
|
|
|
13
|
|
|
|
|
72
|
|
|
|
13
|
|
|
|
|
27
|
|
|
|
13
|
|
|
|
|
309
|
|
|
5
|
13
|
|
|
13
|
|
598
|
use English qw( -no_match_vars ); |
|
|
13
|
|
|
|
|
3865
|
|
|
|
13
|
|
|
|
|
70
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
# FIXME: remove these |
|
8
|
13
|
|
|
13
|
|
3105
|
use vars qw($eval_result @eval_result); |
|
|
13
|
|
|
|
|
26
|
|
|
|
13
|
|
|
|
|
846
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# This is the flag that says "a debugger is running, please call |
|
11
|
|
|
|
|
|
|
# DB::DB and DB::sub". We will turn it on forcibly before we try to |
|
12
|
|
|
|
|
|
|
# execute anything in the user's context, because we always want to |
|
13
|
|
|
|
|
|
|
# get control back. |
|
14
|
13
|
|
|
13
|
|
104
|
use constant db_stop => 1 << 30; |
|
|
13
|
|
|
|
|
33
|
|
|
|
13
|
|
|
|
|
1257
|
|
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
BEGIN { |
|
17
|
|
|
|
|
|
|
# When we want to evaluate a string in the context of the running |
|
18
|
|
|
|
|
|
|
# program we use these: |
|
19
|
13
|
|
|
13
|
|
56
|
$DB::eval_result = undef; # Place for result if scalar; |
|
20
|
13
|
|
|
|
|
32
|
@DB::eval_result = (); # place for result if array |
|
21
|
13
|
|
|
|
|
3078
|
%DB::eval_result = (); # place for result if hash |
|
22
|
|
|
|
|
|
|
} |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# Like builtin caller but we strip off DB:: routines which are presumably |
|
25
|
|
|
|
|
|
|
# are calls from inside inside the debugger (package DB). |
|
26
|
|
|
|
|
|
|
# NOTE: we assume the original builtin caller has been saved inside |
|
27
|
|
|
|
|
|
|
# local-declared *orig_caller. See below in eval_with_return. |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# no critic |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub caller_levels_skip() { |
|
32
|
0
|
|
|
0
|
0
|
0
|
my $skip=0; |
|
33
|
0
|
0
|
|
|
|
0
|
my $db_fn = ($DB::event eq 'post-mortem') ? 'catch' : 'DB'; |
|
34
|
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
0
|
while (my ($pkg, $file, $line, $fn) = caller($skip++)) { |
|
36
|
|
|
|
|
|
|
# Note: The function parameter of caller(), $fn, gives the |
|
37
|
|
|
|
|
|
|
# function that was used rather than the function that the |
|
38
|
|
|
|
|
|
|
# caller is currently in. Therefore, the implicitly line |
|
39
|
|
|
|
|
|
|
# calling DB:DB is the one we want to stop at. |
|
40
|
0
|
0
|
0
|
|
|
0
|
if ("DB::$db_fn" eq $fn or ('DB' eq $pkg && $db_fn eq $fn)) { |
|
|
|
|
0
|
|
|
|
|
|
41
|
|
|
|
|
|
|
## print("XXX $skip\n"); |
|
42
|
0
|
|
|
|
|
0
|
$skip--; |
|
43
|
0
|
|
|
|
|
0
|
last ; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
} |
|
46
|
0
|
0
|
|
|
|
0
|
$skip-- if $skip > 0; |
|
47
|
0
|
|
|
|
|
0
|
return $skip; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Provide a replacement for built-in CORE::caller |
|
51
|
|
|
|
|
|
|
sub caller_sans_DB(;$) { |
|
52
|
0
|
|
|
0
|
0
|
0
|
my $levels = shift; |
|
53
|
0
|
0
|
|
|
|
0
|
$levels = 0 unless defined($levels); |
|
54
|
0
|
|
|
|
|
0
|
my $skip = caller_levels_skip(); |
|
55
|
0
|
|
|
|
|
0
|
my @caller = CORE::caller($skip+$levels); |
|
56
|
|
|
|
|
|
|
|
|
57
|
0
|
0
|
|
|
|
0
|
return if ! @caller; # empty |
|
58
|
0
|
0
|
|
|
|
0
|
return $caller[0] if ! wantarray; # scalar context |
|
59
|
0
|
|
|
|
|
0
|
return @caller[0..2]; # outside of DB, array info just gives 3 itmes |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# evaluate $eval_str in the context of $package_namespace (a package name). |
|
64
|
|
|
|
|
|
|
# @saved contains an ordered list of saved global variables. |
|
65
|
|
|
|
|
|
|
# $return_type indicates the return context: |
|
66
|
|
|
|
|
|
|
# @ for array context, |
|
67
|
|
|
|
|
|
|
# $ for scalar context, |
|
68
|
|
|
|
|
|
|
# % save result in a hash variable |
|
69
|
|
|
|
|
|
|
# |
|
70
|
|
|
|
|
|
|
sub eval_with_return { |
|
71
|
3
|
|
|
3
|
0
|
2760
|
my ($eval_str, $opts, @saved) = @_; |
|
72
|
13
|
|
|
13
|
|
111
|
no strict; |
|
|
13
|
|
|
|
|
35
|
|
|
|
13
|
|
|
|
|
729
|
|
|
73
|
3
|
|
|
|
|
18
|
($EVAL_ERROR, $ERRNO, $EXTENDED_OS_ERROR, |
|
74
|
|
|
|
|
|
|
$OUTPUT_FIELD_SEPARATOR, |
|
75
|
|
|
|
|
|
|
$INPUT_RECORD_SEPARATOR, |
|
76
|
|
|
|
|
|
|
$OUTPUT_RECORD_SEPARATOR, $WARNING) = @saved; |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
{ |
|
79
|
13
|
|
|
13
|
|
72
|
no warnings 'once'; |
|
|
13
|
|
|
|
|
28
|
|
|
|
13
|
|
|
|
|
5758
|
|
|
|
3
|
|
|
|
|
6
|
|
|
80
|
|
|
|
|
|
|
# Try to keep the user code from messing with us. Save these so that |
|
81
|
|
|
|
|
|
|
# even if the eval'ed code changes them, we can put them back again. |
|
82
|
|
|
|
|
|
|
# Needed because the user could refer directly to the debugger's |
|
83
|
|
|
|
|
|
|
# package globals (and any 'my' variables in this containing scope) |
|
84
|
|
|
|
|
|
|
# inside the eval(), and we want to try to stay safe. |
|
85
|
3
|
|
|
|
|
8
|
local $otrace = $DB::trace; |
|
86
|
3
|
|
|
|
|
7
|
local $osingle = $DB::single; |
|
87
|
3
|
|
|
|
|
7
|
local $od = $DEBUGGING; |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# Set package namespace for running eval's in the namespace |
|
90
|
|
|
|
|
|
|
# of the debugged program. |
|
91
|
3
|
|
33
|
|
|
9
|
my $eval_setup = $opts->{namespace_package} || $DB::namespace_package; |
|
92
|
3
|
|
|
|
|
7
|
$eval_setup .= ";\n\@_ = \@DB::_;"; |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# Make sure __FILE__ and __LINE__ are set correctly |
|
95
|
3
|
50
|
|
|
|
24
|
if( $opts->{fix_file_and_line}) { |
|
96
|
0
|
|
|
|
|
0
|
my $position_str = "\n# line $DB::lineno \"$DB::filename\"\n"; |
|
97
|
0
|
|
|
|
|
0
|
$eval_setup .= $position_str ; |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
|
|
100
|
3
|
|
|
|
|
6
|
my $return_type = $opts->{return_type}; |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# Override caller inside the eval below. Many thanks to Toby |
|
103
|
|
|
|
|
|
|
# Inkster and educated_foo via |
|
104
|
|
|
|
|
|
|
# http://www.perlmonks.org/?node_id=1065502 |
|
105
|
|
|
|
|
|
|
|
|
106
|
3
|
|
|
|
|
10
|
local *CORE::GLOBAL::caller = \&caller_sans_DB; |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# Note: our code shouldn't use caller for itself below (or if |
|
109
|
|
|
|
|
|
|
# it is needed use it by the name CORE::caller, since we've |
|
110
|
|
|
|
|
|
|
# overwritten it above. |
|
111
|
|
|
|
|
|
|
|
|
112
|
3
|
100
|
|
|
|
15
|
if ('$' eq $return_type) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# print "+++ eval $return: $eval_setup \$DB::eval_result=$eval_str\n"; |
|
114
|
1
|
|
|
|
|
68
|
eval "$eval_setup \$DB::eval_result=$eval_str\n"; |
|
115
|
|
|
|
|
|
|
} elsif ('@' eq $return_type) { |
|
116
|
|
|
|
|
|
|
# print "+++ eval @return: $eval_setup \@DB::eval_result=$eval_str\n"; |
|
117
|
1
|
|
|
|
|
81
|
eval "$eval_setup \@DB::eval_result=$eval_str\n"; |
|
118
|
|
|
|
|
|
|
} elsif ('%' eq $return_type) { |
|
119
|
1
|
|
|
|
|
69
|
eval "$eval_setup \%DB::eval_result=$eval_str\n"; |
|
120
|
|
|
|
|
|
|
# } elsif ('>' eq $return_type) { |
|
121
|
|
|
|
|
|
|
# ($eval_result, $stderr, @result) = capture { |
|
122
|
|
|
|
|
|
|
# eval "$eval_setup $eval_str\n"; |
|
123
|
|
|
|
|
|
|
# }; |
|
124
|
|
|
|
|
|
|
# } elsif ('2>&1' eq $return_type) { |
|
125
|
|
|
|
|
|
|
# $eval_result = capture_merged { |
|
126
|
|
|
|
|
|
|
# eval "$eval_setup $eval_str\n"; |
|
127
|
|
|
|
|
|
|
} else { |
|
128
|
|
|
|
|
|
|
# print "+++ eval $eval_setup $eval_str\n"; |
|
129
|
0
|
|
|
|
|
0
|
$eval_result = eval "$eval_setup $eval_str\n"; |
|
130
|
|
|
|
|
|
|
}; |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# Restore those old values. |
|
133
|
3
|
|
|
|
|
12
|
$DB::trace = $otrace; |
|
134
|
3
|
|
|
|
|
5
|
$DB::single = $osingle; |
|
135
|
3
|
|
|
|
|
7
|
$DEBUGGING = $od; |
|
136
|
|
|
|
|
|
|
|
|
137
|
3
|
|
|
|
|
6
|
my $msg = $EVAL_ERROR; |
|
138
|
3
|
50
|
|
|
|
9
|
if ($msg) { |
|
139
|
0
|
|
|
|
|
0
|
chomp $msg; |
|
140
|
0
|
0
|
|
|
|
0
|
if ($opts->{hide_position}) { |
|
141
|
0
|
|
|
|
|
0
|
$msg =~ s/ at .* line \d+[.,]//; |
|
142
|
0
|
|
|
|
|
0
|
$msg =~ s/ line \d+,//; |
|
143
|
0
|
|
|
|
|
0
|
$msg =~ s/ at EOF$/ at end of string/; |
|
144
|
|
|
|
|
|
|
} |
|
145
|
0
|
|
|
|
|
0
|
_warnall($msg); |
|
146
|
0
|
|
|
|
|
0
|
$eval_str = ''; |
|
147
|
0
|
|
|
|
|
0
|
return undef; |
|
148
|
|
|
|
|
|
|
} else { |
|
149
|
3
|
100
|
|
|
|
8
|
if ('@' eq $return_type) { |
|
150
|
1
|
|
|
|
|
5
|
return @eval_result; |
|
151
|
|
|
|
|
|
|
} else { |
|
152
|
2
|
|
|
|
|
9
|
return $eval_result; |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Evaluate the argument and return 0 if there's no error. |
|
159
|
|
|
|
|
|
|
# If there is an error we return the error message. |
|
160
|
|
|
|
|
|
|
sub eval_not_ok ($) |
|
161
|
|
|
|
|
|
|
{ |
|
162
|
7
|
|
|
7
|
0
|
10219
|
my $code = shift; |
|
163
|
7
|
|
|
|
|
23
|
my $wrapped = "$DB::namespace_package; sub { $code }"; |
|
164
|
13
|
|
|
13
|
|
103
|
no strict; |
|
|
13
|
|
|
|
|
47
|
|
|
|
13
|
|
|
|
|
3181
|
|
|
165
|
7
|
|
|
1
|
|
525
|
eval $wrapped; |
|
|
1
|
|
|
|
|
21
|
|
|
166
|
7
|
100
|
|
|
|
45
|
if ($@) { |
|
167
|
4
|
|
|
|
|
9
|
my $msg = $@; |
|
168
|
4
|
|
|
|
|
37
|
$msg =~ s/ at .* line \d+[.,]//g; |
|
169
|
4
|
|
|
|
|
17
|
$msg =~ s/ at EOF$/ at end of string/; |
|
170
|
4
|
|
|
|
|
15
|
return $msg; |
|
171
|
|
|
|
|
|
|
} else { |
|
172
|
3
|
|
|
|
|
10
|
return 0; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
unless (CORE::caller) { |
|
177
|
|
|
|
|
|
|
eval { |
|
178
|
|
|
|
|
|
|
sub doit($) { |
|
179
|
0
|
|
|
0
|
0
|
0
|
my $code = shift; |
|
180
|
0
|
|
|
|
|
0
|
my $msg = eval_not_ok($code); |
|
181
|
0
|
|
|
|
|
0
|
print "code: $code\n"; |
|
182
|
0
|
0
|
|
|
|
0
|
if ($msg) { |
|
183
|
0
|
|
|
|
|
0
|
print "$msg"; |
|
184
|
|
|
|
|
|
|
} else { |
|
185
|
0
|
|
|
|
|
0
|
print "code ok\n"; |
|
186
|
|
|
|
|
|
|
} |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
}; |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
$DB::namespace_package = 'package DB;'; |
|
191
|
|
|
|
|
|
|
doit 'doit(1,2,3)'; |
|
192
|
|
|
|
|
|
|
doit "1+"; |
|
193
|
|
|
|
|
|
|
doit '$x+2'; |
|
194
|
|
|
|
|
|
|
doit "foo("; |
|
195
|
|
|
|
|
|
|
doit '$foo ='; |
|
196
|
|
|
|
|
|
|
doit 'BEGIN { $x = 1; '; |
|
197
|
|
|
|
|
|
|
doit 'package foo; 1'; |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
} |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
# doit '$x = 1; __END__ $y='; |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
1; |