line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
|
|
|
|
# Copyright (C) 2012-2015, 2018 Rocky Bernstein <rocky@cpan.org> |
3
|
12
|
|
|
12
|
|
111
|
use strict; use warnings; use utf8; |
|
12
|
|
|
12
|
|
29
|
|
|
12
|
|
|
12
|
|
372
|
|
|
12
|
|
|
|
|
93
|
|
|
12
|
|
|
|
|
33
|
|
|
12
|
|
|
|
|
400
|
|
|
12
|
|
|
|
|
120
|
|
|
12
|
|
|
|
|
46
|
|
|
12
|
|
|
|
|
206
|
|
4
|
12
|
|
|
12
|
|
523
|
use rlib '../../..'; |
|
12
|
|
|
|
|
37
|
|
|
12
|
|
|
|
|
79
|
|
5
|
12
|
|
|
12
|
|
4235
|
use Devel::Trepan::DB::LineCache; # for map_file |
|
12
|
|
|
|
|
39
|
|
|
12
|
|
|
|
|
4565
|
|
6
|
12
|
|
|
12
|
|
92
|
use Devel::Trepan::Complete; |
|
12
|
|
|
|
|
37
|
|
|
12
|
|
|
|
|
1889
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package Devel::Trepan::Processor; |
9
|
|
|
|
|
|
|
|
10
|
12
|
|
|
12
|
|
108
|
use vars qw(@EXPORT @ISA); |
|
12
|
|
|
|
|
27
|
|
|
12
|
|
|
|
|
1097
|
|
11
|
|
|
|
|
|
|
@EXPORT = qw( adjust_frame ); |
12
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
13
|
|
|
|
|
|
|
|
14
|
12
|
|
|
12
|
|
95
|
use English qw( -no_match_vars ); |
|
12
|
|
|
|
|
28
|
|
|
12
|
|
|
|
|
63
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub adjust_frame($$$) |
17
|
|
|
|
|
|
|
{ |
18
|
0
|
|
|
0
|
0
|
0
|
my ($self, $frame_num, $absolute_pos) = @_; |
19
|
0
|
|
|
|
|
0
|
my $frame; |
20
|
0
|
|
|
|
|
0
|
($frame, $frame_num) = $self->get_frame($frame_num, $absolute_pos); |
21
|
0
|
0
|
|
|
|
0
|
if ($frame) { |
22
|
0
|
|
|
|
|
0
|
$self->{frame} = $frame; |
23
|
0
|
|
|
|
|
0
|
$self->{frame_index} = $frame_num; |
24
|
0
|
0
|
|
|
|
0
|
unless ($self->{settings}{traceprint}) { |
25
|
|
|
|
|
|
|
my $opts = { |
26
|
|
|
|
|
|
|
basename => $self->{settings}{basename}, |
27
|
|
|
|
|
|
|
current_pos => $frame_num, |
28
|
|
|
|
|
|
|
maxwidth => $self->{settings}{maxwidth}, |
29
|
|
|
|
|
|
|
displayop => $self->{settings}{displayop}, |
30
|
0
|
|
|
|
|
0
|
}; |
31
|
0
|
|
|
|
|
0
|
$self->print_stack_trace_from_to($frame_num, $frame_num, $self->{frames}, $opts); |
32
|
0
|
|
|
|
|
0
|
$self->print_location ; |
33
|
|
|
|
|
|
|
} |
34
|
0
|
|
|
|
|
0
|
$self->{list_line} = $self->line(); |
35
|
0
|
|
|
|
|
0
|
$self->{list_filename} = $self->filename(); |
36
|
0
|
|
|
|
|
0
|
$self->{frame}; |
37
|
|
|
|
|
|
|
} else { |
38
|
|
|
|
|
|
|
undef |
39
|
0
|
|
|
|
|
0
|
} |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub frame_low_high($;$) |
43
|
|
|
|
|
|
|
{ |
44
|
0
|
|
|
0
|
0
|
0
|
my ($self, $direction) = @_; |
45
|
0
|
0
|
|
|
|
0
|
$direction = 1 unless defined $direction; |
46
|
0
|
|
|
|
|
0
|
my $stack_size = $self->{stack_size}; |
47
|
0
|
|
|
|
|
0
|
my ($low, $high) = (-$stack_size, $stack_size-1); |
48
|
0
|
0
|
|
|
|
0
|
($low, $high) = ($high, $low) if ($direction < 0); |
49
|
0
|
|
|
|
|
0
|
return ($low, $high); |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub frame_setup($$) |
53
|
|
|
|
|
|
|
{ |
54
|
1
|
|
|
1
|
0
|
38
|
my ($self, $frame_aref) = @_; |
55
|
|
|
|
|
|
|
|
56
|
1
|
50
|
|
|
|
4
|
if (defined $frame_aref) { |
57
|
1
|
|
|
|
|
3
|
$self->{frames} = $frame_aref; |
58
|
1
|
|
|
|
|
2
|
$self->{stack_size} = $#{$self->{frames}}+1; |
|
1
|
|
|
|
|
8
|
|
59
|
|
|
|
|
|
|
} else { |
60
|
|
|
|
|
|
|
### FIXME: look go over this code. |
61
|
|
|
|
|
|
|
# $stack_size contains the stack ignoring frames |
62
|
|
|
|
|
|
|
# of this debugger. |
63
|
0
|
|
|
|
|
0
|
my $stack_size = $DB::stack_depth; |
64
|
0
|
|
|
|
|
0
|
my @frames = $self->{dbgr}->tbacktrace(0); |
65
|
0
|
0
|
|
|
|
0
|
@frames = splice(@frames, 2) if $self->{dbgr}{caught_signal}; |
66
|
|
|
|
|
|
|
|
67
|
0
|
0
|
|
|
|
0
|
if ($self->{event} eq 'post-mortem') { |
68
|
0
|
|
|
|
|
0
|
$stack_size = 0; |
69
|
0
|
|
|
|
|
0
|
for my $frame (@frames) { |
70
|
0
|
0
|
0
|
|
|
0
|
next unless defined($frame) && exists($frame->{file}); |
71
|
0
|
|
|
|
|
0
|
$stack_size ++; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
} else { |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# Figure out how many frames this debugger put in. |
76
|
0
|
|
|
|
|
0
|
my $debugger_frames_to_skip=0; |
77
|
0
|
|
|
|
|
0
|
while (my ($pkg, $file, $line, $fn) = |
78
|
|
|
|
|
|
|
caller($debugger_frames_to_skip++)) { |
79
|
0
|
0
|
0
|
|
|
0
|
last if 'DB::DB' eq $fn or ('DB' eq $pkg && 'DB' eq $fn); |
|
|
|
0
|
|
|
|
|
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# Dynamic debugging might not have set $DB::stack_depth |
83
|
|
|
|
|
|
|
# correctly. So we'll doublecheck it here. |
84
|
|
|
|
|
|
|
# $stack_size_with_debugger contains the stack depth |
85
|
|
|
|
|
|
|
# *including* frames added by this debugger. |
86
|
0
|
|
|
|
|
0
|
my $stack_size_with_debugger = $debugger_frames_to_skip; |
87
|
0
|
|
|
|
|
0
|
$stack_size_with_debugger++ while defined caller($stack_size_with_debugger); |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# Adjust for the fact that caller starts at 0; |
90
|
0
|
|
|
|
|
0
|
$stack_size_with_debugger++; |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
0
|
my $computed_stack_depth = |
93
|
|
|
|
|
|
|
$stack_size_with_debugger - $debugger_frames_to_skip; |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# printf("+++ debugger_frames_to_skip: %d, stack_size_with_debugger %d\n", |
96
|
|
|
|
|
|
|
# $debugger_frames_to_skip, $stack_size_with_debugger); |
97
|
|
|
|
|
|
|
# printf("+++ computed_stack_depth: %d DB::stack_depth\n", $computed_stack_depth, $DB::stack_depth); |
98
|
|
|
|
|
|
|
# use Carp qw(cluck); cluck('testing'); |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
## This sometimes happens, but it confused Dmitrios, so remove |
101
|
|
|
|
|
|
|
## for now... |
102
|
|
|
|
|
|
|
# if ((!defined $DB::stack_depth |
103
|
|
|
|
|
|
|
# or $DB::stack_depth < $computed_stack_depth) |
104
|
|
|
|
|
|
|
# and !$self->{gave_stack_trunc_warning}) { |
105
|
|
|
|
|
|
|
# $self->errmsg( |
106
|
|
|
|
|
|
|
# "Call stack depth recorded in DB module is short. We've adjusted it."); |
107
|
|
|
|
|
|
|
# $self->{gave_stack_trunc_warning} = 1; |
108
|
|
|
|
|
|
|
# } |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
0
|
$stack_size = $computed_stack_depth; |
111
|
0
|
0
|
|
|
|
0
|
$stack_size++ if $self->{event} eq 'call'; |
112
|
|
|
|
|
|
|
} |
113
|
0
|
|
|
|
|
0
|
$self->{frames} = \@frames; |
114
|
0
|
|
|
|
|
0
|
$self->{stack_size} = $stack_size; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
1
|
|
|
|
|
4
|
$self->{frame_index} = 0; |
118
|
1
|
|
|
|
|
6
|
$self->{hide_level} = 0; |
119
|
1
|
|
|
|
|
5
|
$self->{frame} = $self->{frames}[0]; |
120
|
1
|
|
|
|
|
15
|
$self->{list_line} = $self->line(); |
121
|
1
|
|
|
|
|
10
|
$self->{list_filename} = $self->filename(); |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub filename($) |
125
|
|
|
|
|
|
|
{ |
126
|
1
|
|
|
1
|
0
|
3
|
my $self = shift; |
127
|
1
|
|
|
|
|
3
|
my $filename = $self->{frame}{file}; |
128
|
1
|
50
|
|
|
|
13
|
if (filename_is_eval($filename)) { |
129
|
0
|
|
|
|
|
0
|
return $filename; |
130
|
|
|
|
|
|
|
} else { |
131
|
1
|
|
|
|
|
10
|
return map_file($filename); |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub funcname($) |
136
|
|
|
|
|
|
|
{ |
137
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
138
|
0
|
|
|
|
|
0
|
$self->{frame}{fn}; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub get_frame($$$) |
142
|
|
|
|
|
|
|
{ |
143
|
0
|
|
|
0
|
0
|
0
|
my ($self, $frame_num, $absolute_pos) = @_; |
144
|
0
|
|
|
|
|
0
|
my $stack_size = $self->{stack_size}; |
145
|
|
|
|
|
|
|
|
146
|
0
|
0
|
|
|
|
0
|
if ($absolute_pos) { |
147
|
0
|
0
|
|
|
|
0
|
$frame_num += $stack_size if $frame_num < 0; |
148
|
|
|
|
|
|
|
} else { |
149
|
0
|
|
|
|
|
0
|
$frame_num += $self->{frame_index}; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
0
|
0
|
|
|
|
0
|
if ($frame_num < 0) { |
|
|
0
|
|
|
|
|
|
153
|
0
|
|
|
|
|
0
|
$self->errmsg('Adjusting would put us beyond the newest frame.'); |
154
|
0
|
|
|
|
|
0
|
return (undef, undef); |
155
|
|
|
|
|
|
|
} elsif ($frame_num >= $stack_size) { |
156
|
0
|
|
|
|
|
0
|
$self->errmsg('Adjusting would put us beyond the oldest frame.'); |
157
|
0
|
|
|
|
|
0
|
return (undef, undef); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
0
|
my $frames = $self->{frames}; |
161
|
0
|
0
|
|
|
|
0
|
unless ($frames->[$frame_num]) { |
162
|
0
|
|
|
|
|
0
|
my @new_frames = $self->{dbgr}->tbacktrace(0); |
163
|
0
|
|
|
|
|
0
|
$self->{frames}[$frame_num] = $new_frames[$frame_num]; |
164
|
|
|
|
|
|
|
} |
165
|
0
|
|
|
|
|
0
|
$self->{frame} = $frames->[$frame_num]; |
166
|
0
|
|
|
|
|
0
|
return ($self->{frame}, $frame_num); |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub line($) |
170
|
|
|
|
|
|
|
{ |
171
|
1
|
|
|
1
|
0
|
3
|
my $self = shift; |
172
|
1
|
|
|
|
|
3
|
$self->{frame}{line}; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub print_stack_entry() |
176
|
|
|
|
|
|
|
{ |
177
|
0
|
|
|
0
|
0
|
|
die "This should have been implemented somewhere else" |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub print_stack_trace_from_to($$$$$) |
181
|
|
|
|
|
|
|
{ |
182
|
0
|
|
|
0
|
0
|
|
die "This should have been implemented somewhere else" |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# Print `count' frame entries |
186
|
|
|
|
|
|
|
sub print_stack_trace($$$) |
187
|
|
|
|
|
|
|
{ |
188
|
0
|
|
|
0
|
0
|
|
die "This should have been implemented somewhere else" |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
1; |