File Coverage

lib/Devel/Trepan/CmdProcessor/Command/Backtrace.pm
Criterion Covered Total %
statement 66 114 57.8
branch 0 12 0.0
condition n/a
subroutine 22 28 78.5
pod 0 6 0.0
total 88 160 55.0


line stmt bran cond sub pod time code
1             # Copyright (C) 2011-2012, 2014-2015, 2018 Rocky Bernstein <rocky@cpan.org>
2 12     12   95 use warnings; no warnings 'redefine';
  12     12   39  
  12     1   388  
  12     1   63  
  12         26  
  12         387  
  1         7  
  1         2  
  1         23  
  1         4  
  1         2  
  1         27  
3              
4 12     12   67 use rlib '../../../..';
  12     1   22  
  12         63  
  1         4  
  1         2  
  1         5  
5              
6             package Devel::Trepan::CmdProcessor::Command::Backtrace;
7 12     12   4744 use if !@ISA, Devel::Trepan::CmdProcessor::Command ;
  12     1   33  
  12         68  
  1         383  
  1         2  
  1         4  
8              
9 12     12   1805 use Getopt::Long qw(GetOptionsFromArray);
  12     1   28  
  12         304  
  1         41  
  1         2  
  1         9  
10              
11             unless (@ISA) {
12 12     12   71 eval <<"EOE";
  12     12   33  
  12     12   912  
  12     12   81  
  12     12   23  
  12     12   571  
  12         67  
  12         45  
  12         563  
  12         68  
  12         29  
  12         766  
  12         76  
  12         24  
  12         536  
  12         63  
  12         33  
  12         518  
13             use constant ALIASES => qw(bt where T);
14             use constant CATEGORY => 'stack';
15             use constant SHORT_HELP => 'Print backtrace of stack frames';
16             use constant MIN_ARGS => 0; # Need at least this many
17             use constant MAX_ARGS => 4; # Need at most this many - undef -> unlimited.
18             use constant NEED_STACK => 1;
19             EOE
20             }
21              
22 12     12   2762 use strict; use vars qw(@ISA); @ISA = @CMD_ISA;
  12     12   26  
  12     1   310  
  12     1   61  
  12         33  
  12         660  
  1         138  
  1         2  
  1         19  
  1         4  
  1         2  
  1         49  
23 12     12   68 use vars @CMD_VARS; # Value inherited from parent
  12     1   29  
  12         8430  
  1         6  
  1         2  
  1         564  
24              
25             our $NAME = set_name();
26             =pod
27              
28             =head2 Synopsis:
29              
30             =cut
31             our $HELP = <<'HELP';
32             =pod
33              
34             B<backtrace> [I<options>] [I<count>]
35              
36             Print backtrace of all stack frames, or innermost *count* frames.
37              
38             With a negative argument, print outermost -I<count> frames.
39              
40             In the listing produced, an arrow, C<--E<gt>>, indicates the 'current
41             frame'. The current frame determines the context used for many
42             debugger commands such as source-line listing
43             (L<C<list>|Devel::Trepan::CmdProcessor::Command::List>) or the
44             L<C<edit>|Devel::Trepan::CmdProcessor::Command::Edit> command.
45              
46             I<optionss> are:
47              
48             -d | --deparse - show deparsed call position
49             -s | --source - show source code line
50             -f | --full - locals of each frame
51             -h | --help - give this help
52              
53             =head2 Examples:
54              
55             backtrace # Print a full stack trace
56             backtrace 2 # Print only the top two entries
57             backtrace -1 # Print a stack trace except the initial (least recent) call.
58             backtrace -s # show source lines in listing
59             backtrace -d # show deparsed source lines in listing
60             backtrace -f # show with locals
61             backtrace -df # show with deparsed calls and locals
62             backtrace --deparse --full # same as above
63              
64             =head2 See also:
65              
66             L<C<up>|Devel::Trepan::CmdProcessor::Command::Up>,
67             L<C<down>|Devel::Trepan::CmdProcessor::Command::Down>, and
68             L<C<frame>|Devel::Trepan::CmdProcessor::Command::Frame>,
69              
70             =cut
71             HELP
72              
73             sub complete($$)
74             {
75 0     0 0   my ($self, $prefix) = @_;
  0     0 0    
76 0           $self->{proc}->frame_complete($prefix);
  0            
77             }
78              
79             my $DEFAULT_OPTIONS = {
80             help => 0, # show source line in backtrace?
81             deparse => 0, # show deparse in backtrace?
82             full => 0, # show "locals"?
83             source => 0, # show source line in backtrace?
84              
85             };
86              
87             sub parse_options($$)
88             {
89 0     0 0   my ($self, $args) = @_;
  0     0 0    
90 0           $Getopt::Long::autoabbrev = 1;
  0            
91 0           my %opts = %{$DEFAULT_OPTIONS};
  0            
  0            
  0            
92             my $result = &GetOptionsFromArray($args,
93             'h|help' => \$opts{help},
94             'd|deparse' => \$opts{deparse},
95             's|source' => \$opts{source},
96             'f|full' => \$opts{full},
97 0           );
  0            
98 0           %opts;
  0            
99             }
100              
101             # This method runs the command
102             sub run($$)
103             {
104 0     0 0   my ($self, $args) = @_;
  0     0 0    
105 0           my $proc = $self->{proc};
  0            
106 0           my %cmd_opts = $self->parse_options($args);
  0            
107             my $opts = {
108             basename => $proc->{settings}{basename},
109             current_pos => $proc->{frame_index},
110             maxstack => $proc->{settings}{maxstack},
111             maxwidth => $proc->{settings}{maxwidth},
112             displayop => $proc->{settings}{displayop},
113             deparse => $cmd_opts{deparse},
114             source => $cmd_opts{source},
115             full => $cmd_opts{full},
116 0           };
  0            
117 0 0         if ($cmd_opts{help}) {
  0 0          
118 0           my $help_cmd = $proc->{commands}{help};
  0            
119 0           $help_cmd->run( ['help', 'backtrace'] );
  0            
120             return
121 0           }
  0            
122              
123 0           my $stack_size = $proc->{stack_size};
  0            
124 0           my $count = $stack_size;
  0            
125 0 0         if (scalar @$args > 1) {
  0 0          
126 0           $count =
  0            
127             $proc->get_an_int($args->[1],
128             {cmdname => $self->name,
129             min_value => -$stack_size,
130             });
131 0 0         return unless defined $count;
  0 0          
132             }
133 0           $opts->{count} = $count;
  0            
134 0           my @frames = $self->{dbgr}->tbacktrace($count-1);
  0            
135 0           $self->{proc}->print_stack_trace(\@frames, $opts);
  0            
136             }
137              
138             unless(caller) {
139             # FIXME: DRY this code by putting in common location.
140             require Devel::Trepan::DB;
141             require Devel::Trepan::Core;
142             my $db = Devel::Trepan::Core->new;
143             my $intf = Devel::Trepan::Interface::User->new(undef, undef, {readline => 0});
144             my $proc = Devel::Trepan::CmdProcessor->new([$intf], $db);
145              
146             $proc->{stack_size} = 0;
147             my $cmd = __PACKAGE__->new($proc);
148             $cmd->run([$NAME]);
149             $cmd->run([$NAME, 1000]);
150             }
151              
152             1;