Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Devel/StackTrace.pm |
Statements | Executed 171626 statements in 186ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
424 | 1 | 1 | 139ms | 216ms | _record_caller_data | Devel::StackTrace::
6775 | 1 | 1 | 58.2ms | 76.9ms | _ref_to_string | Devel::StackTrace::
424 | 1 | 1 | 4.83ms | 221ms | new | Devel::StackTrace::
1 | 1 | 1 | 699µs | 793µs | BEGIN@10 | Devel::StackTrace::
1 | 1 | 1 | 16µs | 16µs | BEGIN@5 | Devel::StackTrace::
1 | 1 | 1 | 10µs | 38µs | BEGIN@12 | Devel::StackTrace::
1 | 1 | 1 | 9µs | 40µs | BEGIN@15 | Devel::StackTrace::
1 | 1 | 1 | 8µs | 12µs | BEGIN@8 | Devel::StackTrace::
1 | 1 | 1 | 8µs | 8µs | BEGIN@11 | Devel::StackTrace::
1 | 1 | 1 | 7µs | 20µs | BEGIN@7 | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | __ANON__[:107] | Devel::StackTrace::
0 | 0 | 0 | 0s | 0s | __ANON__[:144] | 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 | # git description: v1.34-10-g810fd3f | ||||
3 | |||||
4 | 1 | 600ns | $Devel::StackTrace::VERSION = '2.00'; | ||
5 | 2 | 41µs | 1 | 16µs | # spent 16µs within Devel::StackTrace::BEGIN@5 which was called:
# once (16µs+0s) by Exception::Class::Base::BEGIN@7 at line 5 # spent 16µs making 1 call to Devel::StackTrace::BEGIN@5 |
6 | |||||
7 | 2 | 20µs | 2 | 32µs | # spent 20µs (7+13) within Devel::StackTrace::BEGIN@7 which was called:
# once (7µs+13µs) by Exception::Class::Base::BEGIN@7 at line 7 # spent 20µs making 1 call to Devel::StackTrace::BEGIN@7
# spent 13µs making 1 call to strict::import |
8 | 2 | 20µs | 2 | 17µs | # spent 12µs (8+5) within Devel::StackTrace::BEGIN@8 which was called:
# once (8µs+5µs) by Exception::Class::Base::BEGIN@7 at line 8 # spent 12µs making 1 call to Devel::StackTrace::BEGIN@8
# spent 5µs making 1 call to warnings::import |
9 | |||||
10 | 2 | 102µs | 1 | 793µs | # spent 793µs (699+93) within Devel::StackTrace::BEGIN@10 which was called:
# once (699µs+93µs) by Exception::Class::Base::BEGIN@7 at line 10 # spent 793µs making 1 call to Devel::StackTrace::BEGIN@10 |
11 | 2 | 26µs | 1 | 8µs | # spent 8µs within Devel::StackTrace::BEGIN@11 which was called:
# once (8µs+0s) by Exception::Class::Base::BEGIN@7 at line 11 # spent 8µs making 1 call to Devel::StackTrace::BEGIN@11 |
12 | 2 | 34µs | 2 | 67µs | # spent 38µs (10+29) within Devel::StackTrace::BEGIN@12 which was called:
# once (10µs+29µs) by Exception::Class::Base::BEGIN@7 at line 12 # spent 38µs making 1 call to Devel::StackTrace::BEGIN@12
# spent 29µs making 1 call to Exporter::import |
13 | |||||
14 | use overload | ||||
15 | 1 | 500ns | # spent 40µs (9+31) within Devel::StackTrace::BEGIN@15 which was called:
# once (9µs+31µs) by Exception::Class::Base::BEGIN@7 at line 16 | ||
16 | 1 | 968µs | 2 | 71µs | fallback => 1; # spent 40µs making 1 call to Devel::StackTrace::BEGIN@15
# spent 31µs making 1 call to overload::import |
17 | |||||
18 | # spent 221ms (4.83+216) within Devel::StackTrace::new which was called 424 times, avg 520µs/call:
# 424 times (4.83ms+216ms) by Exception::Class::Base::_initialize at line 126 of Exception/Class/Base.pm, avg 520µs/call | ||||
19 | 424 | 92µs | my $class = shift; | ||
20 | 424 | 601µs | my %p = @_; | ||
21 | |||||
22 | 424 | 533µs | $p{unsafe_ref_capture} = !delete $p{no_refs} | ||
23 | if exists $p{no_refs}; | ||||
24 | |||||
25 | 424 | 1.59ms | my $self = bless { | ||
26 | index => undef, | ||||
27 | frames => [], | ||||
28 | raw => [], | ||||
29 | %p, | ||||
30 | }, $class; | ||||
31 | |||||
32 | 424 | 438µs | 424 | 216ms | $self->_record_caller_data(); # spent 216ms making 424 calls to Devel::StackTrace::_record_caller_data, avg 509µs/call |
33 | |||||
34 | 424 | 1.09ms | return $self; | ||
35 | } | ||||
36 | |||||
37 | # spent 216ms (139+76.9) within Devel::StackTrace::_record_caller_data which was called 424 times, avg 509µs/call:
# 424 times (139ms+76.9ms) by Devel::StackTrace::new at line 32, avg 509µs/call | ||||
38 | 424 | 46µs | my $self = shift; | ||
39 | |||||
40 | 424 | 173µs | my $filter = $self->{filter_frames_early} && $self->_make_frame_filter(); | ||
41 | |||||
42 | # We exclude this method by starting at least one frame back. | ||||
43 | 424 | 163µs | my $x = 1 + ( $self->{skip_frames} || 0 ); | ||
44 | |||||
45 | 424 | 14.1ms | 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 | 7342 | 1.29ms | |||
53 | 7342 | 16.3ms | |||
54 | |||||
55 | ) { | ||||
56 | |||||
57 | 6918 | 462µs | my @args; | ||
58 | |||||
59 | 6918 | 12.9ms | @args = $self->{no_args} ? () : @DB::args; | ||
60 | |||||
61 | 6918 | 5.04ms | my $raw = { | ||
62 | caller => \@c, | ||||
63 | args => \@args, | ||||
64 | }; | ||||
65 | |||||
66 | 6918 | 228µs | next if $filter && !$filter->($raw); | ||
67 | |||||
68 | 6918 | 8.58ms | unless ( $self->{unsafe_ref_capture} ) { | ||
69 | 78568 | 23.6ms | 6775 | 76.9ms | $raw->{args} = [ map { ref $_ ? $self->_ref_to_string($_) : $_ } # spent 76.9ms making 6775 calls to Devel::StackTrace::_ref_to_string, avg 11µs/call |
70 | 6918 | 24.1ms | @{ $raw->{args} } ]; | ||
71 | } | ||||
72 | |||||
73 | 6918 | 10.1ms | push @{ $self->{raw} }, $raw; | ||
74 | } | ||||
75 | } | ||||
76 | |||||
77 | # spent 76.9ms (58.2+18.7) within Devel::StackTrace::_ref_to_string which was called 6775 times, avg 11µs/call:
# 6775 times (58.2ms+18.7ms) by Devel::StackTrace::_record_caller_data at line 69, avg 11µs/call | ||||
78 | 6775 | 1.07ms | my $self = shift; | ||
79 | 6775 | 169µs | my $ref = shift; | ||
80 | |||||
81 | 6775 | 48.5ms | 12559 | 11.1ms | return overload::AddrRef($ref) # spent 4.59ms making 6775 calls to Scalar::Util::blessed, avg 677ns/call
# spent 4.43ms making 4373 calls to UNIVERSAL::isa, avg 1µs/call
# spent 2.10ms making 1411 calls to overload::AddrRef, avg 1µs/call |
82 | if blessed $ref && $ref->isa('Exception::Class::Base'); | ||||
83 | |||||
84 | 5364 | 14.0ms | 5364 | 7.55ms | return overload::AddrRef($ref) unless $self->{respect_overload}; # spent 7.55ms making 5364 calls to overload::AddrRef, avg 1µs/call |
85 | |||||
86 | local $@; | ||||
87 | local $SIG{__DIE__}; | ||||
88 | |||||
89 | my $str = eval { $ref . '' }; | ||||
90 | |||||
91 | return $@ ? overload::AddrRef($ref) : $str; | ||||
92 | } | ||||
93 | |||||
94 | sub _make_frames { | ||||
95 | my $self = shift; | ||||
96 | |||||
97 | my $filter = !$self->{filter_frames_early} && $self->_make_frame_filter(); | ||||
98 | |||||
99 | my $raw = delete $self->{raw}; | ||||
100 | for my $r ( @{$raw} ) { | ||||
101 | next if $filter && !$filter->($r); | ||||
102 | |||||
103 | $self->_add_frame( $r->{caller}, $r->{args} ); | ||||
104 | } | ||||
105 | } | ||||
106 | |||||
107 | 1 | 2µs | my $default_filter = sub { 1 }; | ||
108 | |||||
109 | sub _make_frame_filter { | ||||
110 | my $self = shift; | ||||
111 | |||||
112 | my ( @i_pack_re, %i_class ); | ||||
113 | if ( $self->{ignore_package} ) { | ||||
114 | local $@; | ||||
115 | local $SIG{__DIE__}; | ||||
116 | |||||
117 | $self->{ignore_package} = [ $self->{ignore_package} ] | ||||
118 | unless eval { @{ $self->{ignore_package} } }; | ||||
119 | |||||
120 | @i_pack_re | ||||
121 | = map { ref $_ ? $_ : qr/^\Q$_\E$/ } @{ $self->{ignore_package} }; | ||||
122 | } | ||||
123 | |||||
124 | my $p = __PACKAGE__; | ||||
125 | push @i_pack_re, qr/^\Q$p\E$/; | ||||
126 | |||||
127 | if ( $self->{ignore_class} ) { | ||||
128 | $self->{ignore_class} = [ $self->{ignore_class} ] | ||||
129 | unless ref $self->{ignore_class}; | ||||
130 | %i_class = map { $_ => 1 } @{ $self->{ignore_class} }; | ||||
131 | } | ||||
132 | |||||
133 | my $user_filter = $self->{frame_filter}; | ||||
134 | |||||
135 | return sub { | ||||
136 | return 0 if grep { $_[0]{caller}[0] =~ /$_/ } @i_pack_re; | ||||
137 | return 0 if grep { $_[0]{caller}[0]->isa($_) } keys %i_class; | ||||
138 | |||||
139 | if ($user_filter) { | ||||
140 | return $user_filter->( $_[0] ); | ||||
141 | } | ||||
142 | |||||
143 | return 1; | ||||
144 | }; | ||||
145 | } | ||||
146 | |||||
147 | sub _add_frame { | ||||
148 | my $self = shift; | ||||
149 | my $c = shift; | ||||
150 | my $p = shift; | ||||
151 | |||||
152 | # eval and is_require are only returned when applicable under 5.00503. | ||||
153 | push @$c, ( undef, undef ) if scalar @$c == 6; | ||||
154 | |||||
155 | push @{ $self->{frames} }, | ||||
156 | Devel::StackTrace::Frame->new( | ||||
157 | $c, | ||||
158 | $p, | ||||
159 | $self->{respect_overload}, | ||||
160 | $self->{max_arg_length}, | ||||
161 | $self->{message}, | ||||
162 | $self->{indent} | ||||
163 | ); | ||||
164 | } | ||||
165 | |||||
166 | sub next_frame { | ||||
167 | my $self = shift; | ||||
168 | |||||
169 | # reset to top if necessary. | ||||
170 | $self->{index} = -1 unless defined $self->{index}; | ||||
171 | |||||
172 | my @f = $self->frames(); | ||||
173 | if ( defined $f[ $self->{index} + 1 ] ) { | ||||
174 | return $f[ ++$self->{index} ]; | ||||
175 | } | ||||
176 | else { | ||||
177 | $self->{index} = undef; | ||||
178 | return undef; | ||||
179 | } | ||||
180 | } | ||||
181 | |||||
182 | sub prev_frame { | ||||
183 | my $self = shift; | ||||
184 | |||||
185 | my @f = $self->frames(); | ||||
186 | |||||
187 | # reset to top if necessary. | ||||
188 | $self->{index} = scalar @f unless defined $self->{index}; | ||||
189 | |||||
190 | if ( defined $f[ $self->{index} - 1 ] && $self->{index} >= 1 ) { | ||||
191 | return $f[ --$self->{index} ]; | ||||
192 | } | ||||
193 | else { | ||||
194 | $self->{index} = undef; | ||||
195 | return undef; | ||||
196 | } | ||||
197 | } | ||||
198 | |||||
199 | sub reset_pointer { | ||||
200 | my $self = shift; | ||||
201 | |||||
202 | $self->{index} = undef; | ||||
203 | } | ||||
204 | |||||
205 | sub frames { | ||||
206 | my $self = shift; | ||||
207 | |||||
208 | if (@_) { | ||||
209 | die | ||||
210 | "Devel::StackTrace->frames() can only take Devel::StackTrace::Frame args\n" | ||||
211 | if grep { !$_->isa('Devel::StackTrace::Frame') } @_; | ||||
212 | |||||
213 | $self->{frames} = \@_; | ||||
214 | } | ||||
215 | else { | ||||
216 | $self->_make_frames() if $self->{raw}; | ||||
217 | } | ||||
218 | |||||
219 | return @{ $self->{frames} }; | ||||
220 | } | ||||
221 | |||||
222 | sub frame { | ||||
223 | my $self = shift; | ||||
224 | my $i = shift; | ||||
225 | |||||
226 | return unless defined $i; | ||||
227 | |||||
228 | return ( $self->frames() )[$i]; | ||||
229 | } | ||||
230 | |||||
231 | sub frame_count { | ||||
232 | my $self = shift; | ||||
233 | |||||
234 | return scalar( $self->frames() ); | ||||
235 | } | ||||
236 | |||||
237 | sub as_string { | ||||
238 | my $self = shift; | ||||
239 | my $p = shift; | ||||
240 | |||||
241 | my $st = ''; | ||||
242 | my $first = 1; | ||||
243 | foreach my $f ( $self->frames() ) { | ||||
244 | $st .= $f->as_string( $first, $p ) . "\n"; | ||||
245 | $first = 0; | ||||
246 | } | ||||
247 | |||||
248 | return $st; | ||||
249 | } | ||||
250 | |||||
251 | { | ||||
252 | 1 | 300ns | package # hide from PAUSE | ||
253 | Devel::StackTraceFrame; | ||||
254 | |||||
255 | 1 | 6µs | our @ISA = 'Devel::StackTrace::Frame'; | ||
256 | } | ||||
257 | |||||
258 | 1 | 4µs | 1; | ||
259 | |||||
260 | # ABSTRACT: An object representing a stack trace | ||||
261 | |||||
262 | __END__ |