Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Devel/StackTrace.pm |
Statements | Executed 1484 statements in 3.70ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
8 | 1 | 1 | 1.70ms | 2.83ms | _record_caller_data | Devel::StackTrace::
1 | 1 | 1 | 1.52ms | 1.67ms | BEGIN@12 | Devel::StackTrace::
91 | 1 | 1 | 793µs | 1.13ms | _ref_to_string | Devel::StackTrace::
1 | 1 | 1 | 538µs | 606µs | BEGIN@11 | Devel::StackTrace::
8 | 1 | 1 | 167µs | 3.00ms | new | Devel::StackTrace::
1 | 1 | 1 | 11µs | 11µs | BEGIN@6 | Devel::StackTrace::
1 | 1 | 1 | 10µs | 42µs | BEGIN@16 | Devel::StackTrace::
1 | 1 | 1 | 8µs | 34µs | BEGIN@13 | Devel::StackTrace::
1 | 1 | 1 | 7µs | 10µs | BEGIN@9 | Devel::StackTrace::
1 | 1 | 1 | 6µs | 16µs | BEGIN@8 | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | __ANON__[:105] | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | __ANON__[:142] | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | _add_frame | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | _make_frame_filter | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | _make_frames | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | as_string | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | frame | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | frame_count | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | frames | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | next_frame | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | prev_frame | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | reset_pointer | Devel::StackTrace::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Devel::StackTrace; | ||||
2 | { | ||||
3 | 2 | 900ns | $Devel::StackTrace::VERSION = '1.30'; | ||
4 | } | ||||
5 | |||||
6 | 2 | 36µs | 1 | 11µs | # spent 11µs within Devel::StackTrace::BEGIN@6 which was called:
# once (11µs+0s) by Exception::Class::Base::BEGIN@10 at line 6 # spent 11µs making 1 call to Devel::StackTrace::BEGIN@6 |
7 | |||||
8 | 2 | 17µs | 2 | 25µs | # spent 16µs (6+9) within Devel::StackTrace::BEGIN@8 which was called:
# once (6µs+9µs) by Exception::Class::Base::BEGIN@10 at line 8 # spent 16µs making 1 call to Devel::StackTrace::BEGIN@8
# spent 9µs making 1 call to strict::import |
9 | 2 | 19µs | 2 | 13µs | # spent 10µs (7+3) within Devel::StackTrace::BEGIN@9 which was called:
# once (7µs+3µs) by Exception::Class::Base::BEGIN@10 at line 9 # spent 10µs making 1 call to Devel::StackTrace::BEGIN@9
# spent 3µs making 1 call to warnings::import |
10 | |||||
11 | 2 | 75µs | 1 | 606µs | # spent 606µs (538+68) within Devel::StackTrace::BEGIN@11 which was called:
# once (538µs+68µs) by Exception::Class::Base::BEGIN@10 at line 11 # spent 606µs making 1 call to Devel::StackTrace::BEGIN@11 |
12 | 2 | 75µs | 1 | 1.67ms | # spent 1.67ms (1.52+158µs) within Devel::StackTrace::BEGIN@12 which was called:
# once (1.52ms+158µs) by Exception::Class::Base::BEGIN@10 at line 12 # spent 1.67ms making 1 call to Devel::StackTrace::BEGIN@12 |
13 | 2 | 28µs | 2 | 61µs | # spent 34µs (8+26) within Devel::StackTrace::BEGIN@13 which was called:
# once (8µs+26µs) by Exception::Class::Base::BEGIN@10 at line 13 # spent 34µs making 1 call to Devel::StackTrace::BEGIN@13
# spent 26µs making 1 call to Exporter::import |
14 | |||||
15 | use overload | ||||
16 | 1 | 8µs | 1 | 32µs | # spent 42µs (10+32) within Devel::StackTrace::BEGIN@16 which was called:
# once (10µs+32µs) by Exception::Class::Base::BEGIN@10 at line 17 # spent 32µs making 1 call to overload::import |
17 | 1 | 702µs | 1 | 42µs | fallback => 1; # spent 42µs making 1 call to Devel::StackTrace::BEGIN@16 |
18 | |||||
19 | # spent 3.00ms (167µs+2.83) within Devel::StackTrace::new which was called 8 times, avg 375µs/call:
# 8 times (167µs+2.83ms) by Exception::Class::Base::_initialize at line 131 of Exception/Class/Base.pm, avg 375µs/call | ||||
20 | 8 | 4µs | my $class = shift; | ||
21 | 8 | 20µs | my %p = @_; | ||
22 | |||||
23 | # Backwards compatibility - this parameter was renamed to no_refs | ||||
24 | # ages ago. | ||||
25 | 8 | 3µs | $p{no_refs} = delete $p{no_object_refs} | ||
26 | if exists $p{no_object_refs}; | ||||
27 | |||||
28 | 8 | 85µs | my $self = bless { | ||
29 | index => undef, | ||||
30 | frames => [], | ||||
31 | raw => [], | ||||
32 | %p, | ||||
33 | }, $class; | ||||
34 | |||||
35 | 8 | 21µs | 8 | 2.83ms | $self->_record_caller_data(); # spent 2.83ms making 8 calls to Devel::StackTrace::_record_caller_data, avg 354µs/call |
36 | |||||
37 | 8 | 33µs | return $self; | ||
38 | } | ||||
39 | |||||
40 | # spent 2.83ms (1.70+1.13) within Devel::StackTrace::_record_caller_data which was called 8 times, avg 354µs/call:
# 8 times (1.70ms+1.13ms) by Devel::StackTrace::new at line 35, avg 354µs/call | ||||
41 | 8 | 2µs | my $self = shift; | ||
42 | |||||
43 | # We exclude this method by starting one frame back. | ||||
44 | 8 | 2µs | my $x = 1; | ||
45 | 8 | 336µs | while ( | ||
46 | my @c | ||||
47 | = $self->{no_args} | ||||
48 | ? caller( $x++ ) | ||||
49 | : do { | ||||
50 | package # the newline keeps dzil from adding a version here | ||||
51 | DB; | ||||
52 | 113 | 36µs | |||
53 | 113 | 369µs | |||
54 | |||||
55 | ) { | ||||
56 | |||||
57 | 105 | 13µs | my @args; | ||
58 | |||||
59 | 105 | 88µs | unless ( $self->{no_args} ) { | ||
60 | 105 | 74µs | @args = @DB::args; | ||
61 | |||||
62 | 105 | 62µs | if ( $self->{no_refs} ) { | ||
63 | 285 | 415µs | 91 | 1.13ms | @args = map { ref $_ ? $self->_ref_to_string($_) : $_ } @args; # spent 1.13ms making 91 calls to Devel::StackTrace::_ref_to_string, avg 12µs/call |
64 | } | ||||
65 | } | ||||
66 | |||||
67 | 105 | 207µs | push @{ $self->{raw} }, | ||
68 | { | ||||
69 | caller => \@c, | ||||
70 | args => \@args, | ||||
71 | }; | ||||
72 | } | ||||
73 | } | ||||
74 | |||||
75 | # spent 1.13ms (793µs+341µs) within Devel::StackTrace::_ref_to_string which was called 91 times, avg 12µs/call:
# 91 times (793µs+341µs) by Devel::StackTrace::_record_caller_data at line 63, avg 12µs/call | ||||
76 | 91 | 24µs | my $self = shift; | ||
77 | 91 | 14µs | my $ref = shift; | ||
78 | |||||
79 | 91 | 575µs | 145 | 183µs | return overload::AddrRef($ref) # spent 82µs making 91 calls to Scalar::Util::blessed, avg 905ns/call
# spent 81µs making 46 calls to UNIVERSAL::isa, avg 2µs/call
# spent 19µs making 8 calls to overload::AddrRef, avg 2µs/call |
80 | if blessed $ref && $ref->isa('Exception::Class::Base'); | ||||
81 | |||||
82 | 83 | 345µs | 83 | 158µs | return overload::AddrRef($ref) unless $self->{respect_overload}; # spent 158µs making 83 calls to overload::AddrRef, avg 2µs/call |
83 | |||||
84 | local $@; | ||||
85 | local $SIG{__DIE__}; | ||||
86 | |||||
87 | my $str = eval { $ref . '' }; | ||||
88 | |||||
89 | return $@ ? overload::AddrRef($ref) : $str; | ||||
90 | } | ||||
91 | |||||
92 | sub _make_frames { | ||||
93 | my $self = shift; | ||||
94 | |||||
95 | my $filter = $self->_make_frame_filter; | ||||
96 | |||||
97 | my $raw = delete $self->{raw}; | ||||
98 | for my $r ( @{$raw} ) { | ||||
99 | next unless $filter->($r); | ||||
100 | |||||
101 | $self->_add_frame( $r->{caller}, $r->{args} ); | ||||
102 | } | ||||
103 | } | ||||
104 | |||||
105 | 1 | 1µs | my $default_filter = sub { 1 }; | ||
106 | |||||
107 | sub _make_frame_filter { | ||||
108 | my $self = shift; | ||||
109 | |||||
110 | my ( @i_pack_re, %i_class ); | ||||
111 | if ( $self->{ignore_package} ) { | ||||
112 | local $@; | ||||
113 | local $SIG{__DIE__}; | ||||
114 | |||||
115 | $self->{ignore_package} = [ $self->{ignore_package} ] | ||||
116 | unless eval { @{ $self->{ignore_package} } }; | ||||
117 | |||||
118 | @i_pack_re | ||||
119 | = map { ref $_ ? $_ : qr/^\Q$_\E$/ } @{ $self->{ignore_package} }; | ||||
120 | } | ||||
121 | |||||
122 | my $p = __PACKAGE__; | ||||
123 | push @i_pack_re, qr/^\Q$p\E$/; | ||||
124 | |||||
125 | if ( $self->{ignore_class} ) { | ||||
126 | $self->{ignore_class} = [ $self->{ignore_class} ] | ||||
127 | unless ref $self->{ignore_class}; | ||||
128 | %i_class = map { $_ => 1 } @{ $self->{ignore_class} }; | ||||
129 | } | ||||
130 | |||||
131 | my $user_filter = $self->{frame_filter}; | ||||
132 | |||||
133 | return sub { | ||||
134 | return 0 if grep { $_[0]{caller}[0] =~ /$_/ } @i_pack_re; | ||||
135 | return 0 if grep { $_[0]{caller}[0]->isa($_) } keys %i_class; | ||||
136 | |||||
137 | if ($user_filter) { | ||||
138 | return $user_filter->( $_[0] ); | ||||
139 | } | ||||
140 | |||||
141 | return 1; | ||||
142 | }; | ||||
143 | } | ||||
144 | |||||
145 | sub _add_frame { | ||||
146 | my $self = shift; | ||||
147 | my $c = shift; | ||||
148 | my $p = shift; | ||||
149 | |||||
150 | # eval and is_require are only returned when applicable under 5.00503. | ||||
151 | push @$c, ( undef, undef ) if scalar @$c == 6; | ||||
152 | |||||
153 | push @{ $self->{frames} }, | ||||
154 | Devel::StackTrace::Frame->new( | ||||
155 | $c, | ||||
156 | $p, | ||||
157 | $self->{respect_overload}, | ||||
158 | $self->{max_arg_length}, | ||||
159 | $self->{message}, | ||||
160 | $self->{indent} | ||||
161 | ); | ||||
162 | } | ||||
163 | |||||
164 | sub next_frame { | ||||
165 | my $self = shift; | ||||
166 | |||||
167 | # reset to top if necessary. | ||||
168 | $self->{index} = -1 unless defined $self->{index}; | ||||
169 | |||||
170 | my @f = $self->frames(); | ||||
171 | if ( defined $f[ $self->{index} + 1 ] ) { | ||||
172 | return $f[ ++$self->{index} ]; | ||||
173 | } | ||||
174 | else { | ||||
175 | $self->{index} = undef; | ||||
176 | return undef; | ||||
177 | } | ||||
178 | } | ||||
179 | |||||
180 | sub prev_frame { | ||||
181 | my $self = shift; | ||||
182 | |||||
183 | my @f = $self->frames(); | ||||
184 | |||||
185 | # reset to top if necessary. | ||||
186 | $self->{index} = scalar @f unless defined $self->{index}; | ||||
187 | |||||
188 | if ( defined $f[ $self->{index} - 1 ] && $self->{index} >= 1 ) { | ||||
189 | return $f[ --$self->{index} ]; | ||||
190 | } | ||||
191 | else { | ||||
192 | $self->{index} = undef; | ||||
193 | return undef; | ||||
194 | } | ||||
195 | } | ||||
196 | |||||
197 | sub reset_pointer { | ||||
198 | my $self = shift; | ||||
199 | |||||
200 | $self->{index} = undef; | ||||
201 | } | ||||
202 | |||||
203 | sub frames { | ||||
204 | my $self = shift; | ||||
205 | |||||
206 | if (@_) { | ||||
207 | die | ||||
208 | "Devel::StackTrace->frames() can only take Devel::StackTrace::Frame args\n" | ||||
209 | if grep { !$_->isa('Devel::StackTrace::Frame') } @_; | ||||
210 | |||||
211 | $self->{frames} = \@_; | ||||
212 | } | ||||
213 | else { | ||||
214 | $self->_make_frames() if $self->{raw}; | ||||
215 | } | ||||
216 | |||||
217 | return @{ $self->{frames} }; | ||||
218 | } | ||||
219 | |||||
220 | sub frame { | ||||
221 | my $self = shift; | ||||
222 | my $i = shift; | ||||
223 | |||||
224 | return unless defined $i; | ||||
225 | |||||
226 | return ( $self->frames() )[$i]; | ||||
227 | } | ||||
228 | |||||
229 | sub frame_count { | ||||
230 | my $self = shift; | ||||
231 | |||||
232 | return scalar( $self->frames() ); | ||||
233 | } | ||||
234 | |||||
235 | sub as_string { | ||||
236 | my $self = shift; | ||||
237 | my $p = shift; | ||||
238 | |||||
239 | my $st = ''; | ||||
240 | my $first = 1; | ||||
241 | foreach my $f ( $self->frames() ) { | ||||
242 | $st .= $f->as_string( $first, $p ) . "\n"; | ||||
243 | $first = 0; | ||||
244 | } | ||||
245 | |||||
246 | return $st; | ||||
247 | } | ||||
248 | |||||
249 | { | ||||
250 | 1 | 200ns | package | ||
251 | Devel::StackTraceFrame; | ||||
252 | |||||
253 | 1 | 5µs | our @ISA = 'Devel::StackTrace::Frame'; | ||
254 | } | ||||
255 | |||||
256 | 1 | 4µs | 1; | ||
257 | |||||
258 | # ABSTRACT: An object representing a stack trace | ||||
259 | |||||
260 | __END__ |