← Index
NYTProf Performance Profile   « block view • line view • sub view »
For bin/dpath
  Run on Tue Jun 5 15:31:33 2012
Reported on Tue Jun 5 15:31:43 2012

Filename/home/ss5/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Devel/StackTrace.pm
StatementsExecuted 19 statements in 6.57ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1118.71ms9.32msDevel::StackTrace::::BEGIN@12Devel::StackTrace::BEGIN@12
1113.53ms3.93msDevel::StackTrace::::BEGIN@11Devel::StackTrace::BEGIN@11
11174µs74µsDevel::StackTrace::::BEGIN@6Devel::StackTrace::BEGIN@6
11148µs177µsDevel::StackTrace::::BEGIN@16Devel::StackTrace::BEGIN@16
11143µs305µsDevel::StackTrace::::BEGIN@13Devel::StackTrace::BEGIN@13
11134µs34µsDevel::StackTrace::::BEGIN@2Devel::StackTrace::BEGIN@2
11127µs43µsDevel::StackTrace::::BEGIN@8Devel::StackTrace::BEGIN@8
11127µs55µsDevel::StackTrace::::BEGIN@9Devel::StackTrace::BEGIN@9
0000s0sDevel::StackTrace::::__ANON__[:127]Devel::StackTrace::__ANON__[:127]
0000s0sDevel::StackTrace::::__ANON__[:93]Devel::StackTrace::__ANON__[:93]
0000s0sDevel::StackTrace::::_add_frameDevel::StackTrace::_add_frame
0000s0sDevel::StackTrace::::_make_frame_filterDevel::StackTrace::_make_frame_filter
0000s0sDevel::StackTrace::::_make_framesDevel::StackTrace::_make_frames
0000s0sDevel::StackTrace::::_record_caller_dataDevel::StackTrace::_record_caller_data
0000s0sDevel::StackTrace::::_ref_to_stringDevel::StackTrace::_ref_to_string
0000s0sDevel::StackTrace::::as_stringDevel::StackTrace::as_string
0000s0sDevel::StackTrace::::frameDevel::StackTrace::frame
0000s0sDevel::StackTrace::::frame_countDevel::StackTrace::frame_count
0000s0sDevel::StackTrace::::framesDevel::StackTrace::frames
0000s0sDevel::StackTrace::::newDevel::StackTrace::new
0000s0sDevel::StackTrace::::next_frameDevel::StackTrace::next_frame
0000s0sDevel::StackTrace::::prev_frameDevel::StackTrace::prev_frame
0000s0sDevel::StackTrace::::reset_pointerDevel::StackTrace::reset_pointer
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Devel::StackTrace;
2
# spent 34µs within Devel::StackTrace::BEGIN@2 which was called: # once (34µs+0s) by Exception::Class::Base::BEGIN@10 at line 4
BEGIN {
3119µs $Devel::StackTrace::VERSION = '1.27';
4186µs134µs}
# spent 34µs making 1 call to Devel::StackTrace::BEGIN@2
5
62186µs174µs
# spent 74µs within Devel::StackTrace::BEGIN@6 which was called: # once (74µs+0s) by Exception::Class::Base::BEGIN@10 at line 6
use 5.006;
# spent 74µs making 1 call to Devel::StackTrace::BEGIN@6
7
8289µs259µs
# spent 43µs (27+16) within Devel::StackTrace::BEGIN@8 which was called: # once (27µs+16µs) by Exception::Class::Base::BEGIN@10 at line 8
use strict;
# spent 43µs making 1 call to Devel::StackTrace::BEGIN@8 # spent 16µs making 1 call to strict::import
9293µs282µs
# spent 55µs (27+28) within Devel::StackTrace::BEGIN@9 which was called: # once (27µs+28µs) by Exception::Class::Base::BEGIN@10 at line 9
use warnings;
# spent 55µs making 1 call to Devel::StackTrace::BEGIN@9 # spent 28µs making 1 call to warnings::import
10
112453µs13.93ms
# spent 3.93ms (3.53+406µs) within Devel::StackTrace::BEGIN@11 which was called: # once (3.53ms+406µs) by Exception::Class::Base::BEGIN@10 at line 11
use Devel::StackTrace::Frame;
# spent 3.93ms making 1 call to Devel::StackTrace::BEGIN@11
122489µs19.32ms
# spent 9.32ms (8.71+618µs) within Devel::StackTrace::BEGIN@12 which was called: # once (8.71ms+618µs) by Exception::Class::Base::BEGIN@10 at line 12
use File::Spec;
# spent 9.32ms making 1 call to Devel::StackTrace::BEGIN@12
132158µs2567µs
# spent 305µs (43+262) within Devel::StackTrace::BEGIN@13 which was called: # once (43µs+262µs) by Exception::Class::Base::BEGIN@10 at line 13
use Scalar::Util qw( blessed );
# spent 305µs making 1 call to Devel::StackTrace::BEGIN@13 # spent 262µs making 1 call to Exporter::import
14
15use overload
161129µs
# spent 177µs (48+129) within Devel::StackTrace::BEGIN@16 which was called: # once (48µs+129µs) by Exception::Class::Base::BEGIN@10 at line 17
'""' => \&as_string,
# spent 129µs making 1 call to overload::import
1724.93ms1177µs fallback => 1;
# spent 177µs making 1 call to Devel::StackTrace::BEGIN@16
18
19sub new {
20 my $class = shift;
21 my %p = @_;
22
23 # Backwards compatibility - this parameter was renamed to no_refs
24 # ages ago.
25 $p{no_refs} = delete $p{no_object_refs}
26 if exists $p{no_object_refs};
27
28 my $self = bless {
29 index => undef,
30 frames => [],
31 raw => [],
32 %p,
33 }, $class;
34
35 $self->_record_caller_data();
36
37 return $self;
38}
39
40sub _record_caller_data {
41 my $self = shift;
42
43 # We exclude this method by starting one frame back.
44 my $x = 1;
45 while (
46 my @c
47 = do { package # the newline keeps dzil from adding a version here
48 DB; @DB::args = (); caller( $x++ ) }
49 ) {
50 my @args = @DB::args;
51
52 if ( $self->{no_refs} ) {
53 @args = map { ref $_ ? $self->_ref_to_string($_) : $_ } @args;
54 }
55
56 push @{ $self->{raw} }, {
57 caller => \@c,
58 args => \@args,
59 };
60 }
61}
62
63sub _ref_to_string {
64 my $self = shift;
65 my $ref = shift;
66
67 return overload::AddrRef($ref)
68 if blessed $ref && $ref->isa('Exception::Class::Base');
69
70 return overload::AddrRef($ref) unless $self->{respect_overload};
71
72 local $@;
73 local $SIG{__DIE__};
74
75 my $str = eval { $ref . '' };
76
77 return $@ ? overload::AddrRef($ref) : $str;
78}
79
80sub _make_frames {
81 my $self = shift;
82
83 my $filter = $self->_make_frame_filter;
84
85 my $raw = delete $self->{raw};
86 for my $r ( @{$raw} ) {
87 next unless $filter->($r);
88
89 $self->_add_frame( $r->{caller}, $r->{args} );
90 }
91}
92
93112µsmy $default_filter = sub {1};
94
95sub _make_frame_filter {
96 my $self = shift;
97
98 my ( @i_pack_re, %i_class );
99 if ( $self->{ignore_package} ) {
100 $self->{ignore_package} = [ $self->{ignore_package} ]
101 unless UNIVERSAL::isa( $self->{ignore_package}, 'ARRAY' );
102
103 @i_pack_re
104 = map { ref $_ ? $_ : qr/^\Q$_\E$/ } @{ $self->{ignore_package} };
105 }
106
107 my $p = __PACKAGE__;
108 push @i_pack_re, qr/^\Q$p\E$/;
109
110 if ( $self->{ignore_class} ) {
111 $self->{ignore_class} = [ $self->{ignore_class} ]
112 unless ref $self->{ignore_class};
113 %i_class = map { $_ => 1 } @{ $self->{ignore_class} };
114 }
115
116 my $user_filter = $self->{frame_filter};
117
118 return sub {
119 return 0 if grep { $_[0]{caller}[0] =~ /$_/ } @i_pack_re;
120 return 0 if grep { $_[0]{caller}[0]->isa($_) } keys %i_class;
121
122 if ($user_filter) {
123 return $user_filter->( $_[0] );
124 }
125
126 return 1;
127 };
128}
129
130sub _add_frame {
131 my $self = shift;
132 my $c = shift;
133 my $args = shift;
134
135 # eval and is_require are only returned when applicable under 5.00503.
136 push @$c, ( undef, undef ) if scalar @$c == 6;
137
138 if ( $self->{no_refs} ) {
139 }
140
141 push @{ $self->{frames} },
142 Devel::StackTrace::Frame->new(
143 $c,
144 $args,
145 $self->{respect_overload},
146 $self->{max_arg_length},
147 $self->{message},
148 $self->{indent}
149 );
150}
151
152sub next_frame {
153 my $self = shift;
154
155 # reset to top if necessary.
156 $self->{index} = -1 unless defined $self->{index};
157
158 my @f = $self->frames();
159 if ( defined $f[ $self->{index} + 1 ] ) {
160 return $f[ ++$self->{index} ];
161 }
162 else {
163 $self->{index} = undef;
164 return undef;
165 }
166}
167
168sub prev_frame {
169 my $self = shift;
170
171 my @f = $self->frames();
172
173 # reset to top if necessary.
174 $self->{index} = scalar @f unless defined $self->{index};
175
176 if ( defined $f[ $self->{index} - 1 ] && $self->{index} >= 1 ) {
177 return $f[ --$self->{index} ];
178 }
179 else {
180 $self->{index} = undef;
181 return undef;
182 }
183}
184
185sub reset_pointer {
186 my $self = shift;
187
188 $self->{index} = undef;
189}
190
191sub frames {
192 my $self = shift;
193
194 $self->_make_frames() if $self->{raw};
195
196 return @{ $self->{frames} };
197}
198
199sub frame {
200 my $self = shift;
201 my $i = shift;
202
203 return unless defined $i;
204
205 return ( $self->frames() )[$i];
206}
207
208sub frame_count {
209 my $self = shift;
210
211 return scalar( $self->frames() );
212}
213
214sub as_string {
215 my $self = shift;
216
217 my $st = '';
218 my $first = 1;
219 foreach my $f ( $self->frames() ) {
220 $st .= $f->as_string($first) . "\n";
221 $first = 0;
222 }
223
224 return $st;
225}
226
227{
22812µs package
229 Devel::StackTraceFrame;
230
231129µs our @ISA = 'Devel::StackTrace::Frame';
232}
233
234121µs1;
235
236# ABSTRACT: An object representing a stack trace
237
- -
240=pod
241
242=head1 NAME
243
244Devel::StackTrace - An object representing a stack trace
245
246=head1 VERSION
247
248version 1.27
249
250=head1 SYNOPSIS
251
252 use Devel::StackTrace;
253
254 my $trace = Devel::StackTrace->new;
255
256 print $trace->as_string; # like carp
257
258 # from top (most recent) of stack to bottom.
259 while (my $frame = $trace->next_frame) {
260 print "Has args\n" if $frame->hasargs;
261 }
262
263 # from bottom (least recent) of stack to top.
264 while (my $frame = $trace->prev_frame) {
265 print "Sub: ", $frame->subroutine, "\n";
266 }
267
268=head1 DESCRIPTION
269
270The Devel::StackTrace module contains two classes, Devel::StackTrace
271and Devel::StackTrace::Frame. The goal of this object is to encapsulate
272the information that can found through using the caller() function, as
273well as providing a simple interface to this data.
274
275The Devel::StackTrace object contains a set of Devel::StackTrace::Frame
276objects, one for each level of the stack. The frames contain all the
277data available from C<caller()>.
278
279This code was created to support my L<Exception::Class::Base> class
280(part of Exception::Class) but may be useful in other contexts.
281
282=head1 'TOP' AND 'BOTTOM' OF THE STACK
283
284When describing the methods of the trace object, I use the words 'top'
285and 'bottom'. In this context, the 'top' frame on the stack is the
286most recent frame and the 'bottom' is the least recent.
287
288Here's an example:
289
290 foo(); # bottom frame is here
291
292 sub foo {
293 bar();
294 }
295
296 sub bar {
297 Devel::StackTrace->new; # top frame is here.
298 }
299
300=head1 Devel::StackTrace METHODS
301
302=over 4
303
304=item * Devel::StackTrace->new(%named_params)
305
306Returns a new Devel::StackTrace object.
307
308Takes the following parameters:
309
310=over 8
311
312=item * frame_filter => $sub
313
314By default, Devel::StackTrace will include all stack frames before the
315call to its its constructor.
316
317However, you may want to filter out some frames with more granularity
318than 'ignore_package' or 'ignore_class' allow.
319
320You can provide a subroutine which is called with the raw frame data
321for each frame. This is a hash reference with two keys, "caller", and
322"args", both of which are array references. The "caller" key is the
323raw data as returned by Perl's C<caller()> function, and the "args"
324key are the subroutine arguments found in C<@DB::args>.
325
326The filter should return true if the frame should be included, or
327false if it should be skipped.
328
329=item * ignore_package => $package_name OR \@package_names
330
331Any frames where the package is one of these packages will not be on
332the stack.
333
334=item * ignore_class => $package_name OR \@package_names
335
336Any frames where the package is a subclass of one of these packages
337(or is the same package) will not be on the stack.
338
339Devel::StackTrace internally adds itself to the 'ignore_package'
340parameter, meaning that the Devel::StackTrace package is B<ALWAYS>
341ignored. However, if you create a subclass of Devel::StackTrace it
342will not be ignored.
343
344=item * no_refs => $boolean
345
346If this parameter is true, then Devel::StackTrace will not store
347references internally when generating stacktrace frames. This lets
348your objects go out of scope.
349
350Devel::StackTrace replaces any references with their stringified
351representation.
352
353=item * respect_overload => $boolean
354
355By default, Devel::StackTrace will call C<overload::AddrRef()> to get
356the underlying string representation of an object, instead of
357respecting the object's stringification overloading. If you would
358prefer to see the overloaded representation of objects in stack
359traces, then set this parameter to true.
360
361=item * max_arg_length => $integer
362
363By default, Devel::StackTrace will display the entire argument for
364each subroutine call. Setting this parameter causes it to truncate the
365argument's string representation if it is longer than this number of
366characters.
367
368=item * message => $string
369
370By default, Devel::StackTrace will use 'Trace begun' as the message for the
371first stack frame when you call C<as_string>. You can supply an alternative
372message using this option.
373
374=item * indent => $boolean
375
376If this parameter is true, each stack frame after the first will start with a
377tab character, just like C<Carp::confess()>.
378
379=back
380
381=item * $trace->next_frame
382
383Returns the next Devel::StackTrace::Frame object down on the stack. If
384it hasn't been called before it returns the first frame. It returns
385undef when it reaches the bottom of the stack and then resets its
386pointer so the next call to C<next_frame> or C<prev_frame> will work
387properly.
388
389=item * $trace->prev_frame
390
391Returns the next Devel::StackTrace::Frame object up on the stack. If it
392hasn't been called before it returns the last frame. It returns undef
393when it reaches the top of the stack and then resets its pointer so
394pointer so the next call to C<next_frame> or C<prev_frame> will work
395properly.
396
397=item * $trace->reset_pointer
398
399Resets the pointer so that the next call C<next_frame> or
400C<prev_frame> will start at the top or bottom of the stack, as
401appropriate.
402
403=item * $trace->frames
404
405Returns a list of Devel::StackTrace::Frame objects. The order they are
406returned is from top (most recent) to bottom.
407
408=item * $trace->frame ($index)
409
410Given an index, returns the relevant frame or undef if there is not
411frame at that index. The index is exactly like a Perl array. The
412first frame is 0 and negative indexes are allowed.
413
414=item * $trace->frame_count
415
416Returns the number of frames in the trace object.
417
418=item * $trace->as_string
419
420Calls as_string on each frame from top to bottom, producing output
421quite similar to the Carp module's cluck/confess methods.
422
423=back
424
425=head1 SUPPORT
426
427Please submit bugs to the CPAN RT system at
428http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel%3A%3AStackTrace
429or via email at bug-devel-stacktrace@rt.cpan.org.
430
431=head1 AUTHOR
432
433Dave Rolsky <autarch@urth.org>
434
435=head1 COPYRIGHT AND LICENSE
436
437This software is Copyright (c) 2011 by Dave Rolsky.
438
439This is free software, licensed under:
440
441 The Artistic License 2.0 (GPL Compatible)
442
443=cut
444
445
446__END__