File Coverage

lib/Devel/Trepan/DB.pm
Criterion Covered Total %
statement 80 349 22.9
branch 3 122 2.4
condition 0 68 0.0
subroutine 24 51 47.0
pod 7 25 28.0
total 114 615 18.5


line stmt bran cond sub pod time code
1             # Perl's Core DB.pm library with some corrections, additions,
2             # modifications and code merged from perl5db.pl
3             #
4             # Documentation is after __END__
5             #
6              
7 12     12   79 use rlib '../..';
  12         29  
  12         76  
8              
9 12     12   11201 use Devel::Callsite;
  12         7986  
  12         1050  
10              
11             =pod
12              
13             =head1 C<DB>
14              
15             Devel::Trepan customized DB package. Down the line this should be split off
16             and merged with DB that perl5db.pl and other uses similar ilk.
17              
18             =cut
19              
20             package DB;
21 12     12   92 use warnings; no warnings 'redefine';
  12     12   32  
  12         321  
  12         68  
  12         29  
  12         393  
22 12     12   541 use English qw( -no_match_vars );
  12         1268  
  12         111  
23 12     12   4054 use version;
  12         1462  
  12         107  
24              
25 12     12   6714 use Devel::Trepan::DB::Vars;
  12         39  
  12         435  
26 12     12   4962 use Devel::Trepan::DB::Backtrace;
  12         39  
  12         343  
27 12     12   382 use Devel::Trepan::DB::Breakpoint;
  12         31  
  12         225  
28 12     12   5045 use Devel::Trepan::DB::Eval;
  12         40  
  12         330  
29 12     12   846 use Devel::Trepan::DB::Sub;
  12         29  
  12         293  
30 12     12   5475 use Devel::Trepan::Terminated;
  12         39  
  12         577  
31              
32             # "private" globals
33             my (@skippkg);
34              
35             my $ineval = {};
36              
37             ####
38             #
39             # Globals - must be defined at startup so that clients can refer to
40             # them right after a C<use Devel::Trepan::DB;>
41             #
42             ####
43              
44             BEGIN {
45 12     12   74 no warnings 'once';
  12         28  
  12         1018  
46 12     12   56 $ini_warn = $WARNING;
47              
48 12         26 $in_debugger = 0;
49 12         34 @clients = ();
50 12         32 $ready = 0;
51 12         26 @DB::saved = ();
52 12         30 @skippkg = ();
53              
54             # ensure we can share our non-threaded variables or no-op
55 12 50       70 if ($ENV{PERL5DB_THREADED}) {
56 0         0 require threads;
57 0         0 require threads::shared;
58 0         0 import threads::shared qw(share);
59 12     12   99 no strict; no warnings;
  12     12   32  
  12         259  
  12         75  
  12         49  
  12         595  
60 0         0 $DBGR;
61 0         0 share(\$DBGR);
62 0         0 lock($DBGR);
63 12     12   74 use strict; use warnings;
  12     12   30  
  12         238  
  12         56  
  12         43  
  12         1361  
64 0         0 print "Thread support enabled\n";
65             } else {
66 12     0   64 *lock = sub(*) {};
67 12     0   43 *share = sub(*) {};
68             }
69              
70             # Don't print return values on exiting a subroutine.
71 12         30 $doret = -2;
72              
73             # "Triggers bug (?) in perl if we postpone this until runtime."
74             # XXX No details on this yet, or whether we should fix the bug instead
75             # of work around it. Stay tuned.
76 12         37 @postponed = @stack = (0);
77              
78             # No extry/exit tracing.
79 12         29 $frame = 0;
80 12         4149 $HAVE_MODULE{'Devel::Callsite'} = 'call_level_param';
81             }
82              
83             END {
84 12 50   12   64086 unless ($DB::fall_off_on_end) {
85 12         64 $DB::single = 1;
86 12         84 Devel::Trepan::Terminated::at_exit();
87             }
88 12         116 $DB::ready = 0;
89             }
90              
91             sub save_vars();
92              
93             ####
94             # This is called by Perl for every statement
95             #
96             # IMPORTANT NOTE: We allow DB:DB() to get called recursively and due
97             # to Perl bug RT #115742 and advisement from Ben Morrow, we shouldn't
98             # use lexical variables on versions of Perl before 5.18.0.
99             #
100             sub DB
101             {
102              
103             # print "+++ in DB single: ${DB::single}\n";
104              
105             # lock the debugger and get the thread id for the prompt
106 0 0   0 0 0 if ($ENV{PERL5DB_THREADED}) {
107 0         0 lock($DBGR);
108 0         0 $tid = eval { "[".threads->tid."]" };
  0         0  
109             }
110              
111 0 0 0     0 return unless $ready && !$in_debugger;
112 0         0 local $in_debugger = 1;
113 0         0 @DB::_ = @_;
114 0         0 save_vars();
115              
116             # Since DB::DB gets called after every line, we can use caller() to
117             # figure out where we last were executing. Sneaky, eh? This works because
118             # caller is returning all the extra information when called from the
119             # debugger.
120 0         0 $DB::caller = [CORE::caller];
121             ($DB::package, $DB::filename, $DB::lineno, $DB::subroutine, $DB::hasargs,
122             $DB::wantarray, $DB::evaltext, $DB::is_require, $DB::hints, $DB::bitmask,
123             $DB::hinthash
124 0         0 ) = @{$DB::caller};
  0         0  
125              
126             # print "++++ $DB::package $DB::filename, $DB::lineno\n";
127 0         0 local $filename_ini = $filename;
128              
129 0         0 local $OP_addr = Devel::Callsite::callsite();
130              
131 0 0 0     0 return if @skippkg and grep { $_ eq $DB::package } @skippkg;
  0         0  
132              
133             # Set package namespace for running eval's in the user context.
134             # However this won't let them modify lexical variables, alas.
135             # This has to be 'local' rather than 'my' to allow recursive
136             # debugging ("debug" command).
137 0         0 local $namespace_package = "package $DB::package;";
138              
139 0         0 local(*DB::dbline) = "::_<$DB::filename";
140              
141             # we need to check for pseudofiles on Mac OS (these are files
142             # not attached to a filename, but instead stored in Dev:Pseudo)
143 0 0 0     0 if ( $OSNAME eq 'MacOS' && $#dbline < 0 ) {
144 0         0 $filename_ini = $filename = 'Dev:Pseudo';
145 0         0 *dbline = $main::{ '_<' . $filename };
146             }
147 0         0 $DB::brkpt = undef;
148              
149             # Increment debugger nesting level.
150 0         0 local $DB::level = $DB::level + 1;
151              
152             # Test watch expressions;
153 0         0 local $watch_triggered = undef;
154 0         0 local $c;
155 0         0 for $c (@clients) {
156 0         0 local @list= @{$c->{watch}->{list}};
  0         0  
157 0         0 local $wp;
158 0         0 for $wp (@list) {
159 0 0       0 next unless $wp->enabled;
160 0         0 local $opts = {return_type => '$',
161             namespace_package => $namespace_package,
162             fix_file_and_line => 1,
163             hide_position => 0};
164 0         0 local $new_val = &DB::eval_with_return($wp->expr, $opts, @DB::saved);
165 0         0 local $old_val = $wp->old_value;
166 12     12   87 no warnings 'once';
  12         28  
  12         13645  
167 0 0 0     0 next if !defined($old_value) and !defined($new_val);
168 0   0     0 local $not_same = !defined($old_val) || !defined($new_val);
169 0 0 0     0 if ( $not_same || $new_val ne $wp->old_value ) {
170             # Yep! Record change.
171 0         0 $wp->current_val($new_val);
172 0         0 $wp->hits($wp->hits+1);
173 0         0 $watch_triggered = $wp;
174 0         0 last;
175             }
176             }
177             }
178              
179             # Test for breakpoints and action events.
180 0         0 local @action = ();
181 0 0 0     0 if (exists $DB::dbline{$DB::lineno} and
182             local $brkpts = $DB::dbline{$DB::lineno}) {
183 0         0 for (local $i=0; $i < @$brkpts; $i++) {
184 0         0 local $brkpt = $brkpts->[$i];
185 0 0       0 next unless defined $brkpt;
186 0 0       0 if ($brkpt->type eq 'action') {
187 0         0 push @action, $brkpt;
188 0         0 next ;
189             }
190 0         0 $stop = 0;
191 0 0       0 if ($brkpt->condition eq '1') {
192             # A cheap and simple test for unconditional.
193 0         0 $stop = 1;
194             } else {
195 0         0 my $eval_str = sprintf("\$DB::stop = do { %s; }",
196             $brkpt->condition);
197 0         0 my $opts = {return_type => ';', # ignore return
198             namespace_package => $namespace_package,
199             fix_file_and_line => 1,
200             hide_position => 0};
201 0         0 &DB::eval_with_return($eval_str, $opts, @DB::saved);
202             }
203 0 0 0     0 if ($stop && $brkpt->enabled && !($DB::single & RETURN_EVENT)) {
      0        
204 0         0 $DB::signal |= 1;
205 0         0 $DB::brkpt = $brkpt;
206 0         0 $event = $brkpt->type;
207 0 0       0 if ($event eq 'tbrkpt') {
208             # breakpoint is temporary and remove it.
209 0         0 undef $brkpts->[$i];
210             } else {
211 0         0 my $hits = $brkpt->hits + 1;
212 0         0 $brkpt->hits($hits);
213             }
214 0         0 last;
215             }
216             }
217             }
218 0 0       0 if ($watch_triggered) {
    0          
    0          
    0          
    0          
    0          
219 0         0 $event = 'watch';
220             } elsif ($DB::signal) {
221 0   0     0 $event ||= 'signal';
222             } elsif ($DB::single & RETURN_EVENT) {
223 0         0 $event = 'return';
224             } elsif ($DB::trace ) {
225 0   0     0 $event ||= 'trace';
226             } elsif ($DB::single & (SINGLE_STEPPING_EVENT | NEXT_STEPPING_EVENT)) {
227 0   0     0 $event ||= 'line';
228             } elsif ($DB::single & DEEP_RECURSION_EVENT) {
229 0   0     0 $event ||= 'recurse overflow';
230             } else {
231 0         0 $event = 'unknown';
232             }
233              
234 0 0 0     0 if ($DB::single || $DB::trace || $DB::signal || $event eq 'watch') {
      0        
      0        
235 0 0       0 $DB::subname = ($DB::sub =~ /\'|::/) ? $DB::sub : "${DB::package}::$DB::sub"; #';
236 0         0 loadfile($DB::filename, $DB::lineno);
237             }
238              
239 0         0 local $action;
240 0         0 for $action (@action) {
241 0 0       0 &DB::eval_with_return($action->condition, {return_type => '$'},
242             @DB::saved)
243             if $action->enabled;
244 0         0 my $hits = $action->hits + 1;
245 0         0 $action->hits($hits);
246             }
247              
248 0 0 0     0 if ($DB::single || $DB::signal || $watch_triggered) {
      0        
249 0 0       0 _warnall($#stack . " levels deep in subroutine calls.\n") if $DB::single & 4;
250 0         0 $DB::single = 0;
251 0         0 $DB::signal = 0;
252 0         0 $DB::running = 0;
253              
254             # FIXME: give a warning...
255 0         0 $DB::bt_truncated = defined caller($DB::stack_depth+1);
256 0         0 $DB::stack_depth++ while defined caller($DB::stack_depth+1);
257              
258 0         0 local $c;
259 0         0 for $c (@clients) {
260             # Now sit in an event loop until something sets $running
261 0         0 local $after_eval = 0;
262 0         0 do {
263             # Show display expresions
264 0         0 local $display_aref = $c->display_lists;
265 0         0 local $disp;
266 0         0 for $disp (@$display_aref) {
267 0 0 0     0 next unless $disp && $disp->enabled;
268 0         0 local $opts = {return_type => $disp->return_type,
269             namespace_package => $namespace_package,
270             fix_file_and_line => 1,
271             hide_position => 0};
272             # FIXME: allow more than just scalar contexts.
273 0         0 local $eval_result =
274             &DB::eval_with_return($disp->arg, $opts, @DB::saved);
275 0         0 local $mess;
276 0 0       0 if (defined($eval_result)) {
277 0         0 $mess = sprintf("%d: $eval_result", $disp->number);
278             } else {
279 0         0 $mess = sprintf("%d: undef", $disp->number);
280             }
281 0         0 $c->output($mess);
282             }
283              
284 0 0       0 if (1 == $after_eval ) {
    0          
285 0         0 $event = 'after_eval';
286             } elsif (2 == $after_eval) {
287 0         0 $event = 'after_nest'
288             }
289              
290             # call client event loop; must not block
291 0         0 $c->idle($event, $watch_triggered);
292 0         0 $after_eval = 0;
293 0 0 0     0 if ($running == 2 && defined($eval_str)) {
294             # client wants something eval-ed
295             # FIXME: turn into subroutine.
296              
297 0         0 local $nest = $eval_opts->{nest};
298 0         0 my $return_type = $eval_opts->{return_type};
299 0 0       0 $return_type = '' unless defined $return_type;
300 0         0 my $opts = $eval_opts;
301 0         0 $opts->{namespace_package} = $namespace_package;
302              
303 0 0       0 if ('@' eq $return_type) {
    0          
304 0         0 &DB::eval_with_return($eval_str, $opts, @DB::saved);
305             } elsif ('%' eq $return_type) {
306 0         0 &DB::eval_with_return($eval_str, $opts, @DB::saved);
307             } else {
308 0         0 $eval_result =
309             &DB::eval_with_return($eval_str, $opts, @DB::saved);
310             }
311              
312 0 0       0 if ($nest) {
313 0         0 $DB::in_debugger = 1;
314 0         0 $after_eval = 2;
315             } else {
316 0         0 $after_eval = 1;
317             }
318 0         0 $DB::running = 0;
319             }
320             } until $running;
321             }
322             }
323              
324 0         0 $DB::event = undef;
325 0         0 ($EVAL_ERROR, $ERRNO, $EXTENDED_OS_ERROR,
326             $OUTPUT_FIELD_SEPARATOR,
327             $INPUT_RECORD_SEPARATOR,
328             $OUTPUT_RECORD_SEPARATOR, $WARNING) = @DB::saved;
329 0         0 ();
330             }
331              
332             =head1 RESTART SUPPORT
333              
334             These routines are used to store (and restore) lists of items in environment
335             variables during a restart.
336              
337             =head2 set_list
338              
339             Set_list packages up items to be stored in a set of environment variables
340             (VAR_n, containing the number of items, and VAR_0, VAR_1, etc., containing
341             the values). Values outside the standard ASCII charset are stored by encoding
342             then as hexadecimal values.
343              
344             =cut
345              
346             sub set_list
347             {
348 0     0 0 0 my ( $stem, @list ) = @_;
349 0         0 my $val;
350              
351             # VAR_n: how many we have. Scalar assignment gets the number of items.
352 0         0 $ENV{"${stem}_n"} = @list;
353              
354             # Grab each item in the list, escape the backslashes, encode the non-ASCII
355             # as hex, and then save in the appropriate VAR_0, VAR_1, etc.
356 0         0 for $i ( 0 .. $#list ) {
357 0         0 $val = $list[$i];
358 0         0 $val =~ s/\\/\\\\/g;
359 0         0 $val =~ s/([\0-\37\177\200-\377])/"\\0x" . unpack('H2',$1)/eg;
  0         0  
360 0         0 $ENV{"${stem}_$i"} = $val;
361             } ## end for $i (0 .. $#list)
362             } ## end sub set_list
363              
364             =head2 get_list
365              
366             Reverse the set_list operation: grab VAR_n to see how many we should be getting
367             back, and then pull VAR_0, VAR_1. etc. back out.
368              
369             =cut
370              
371             sub get_list {
372 0     0 0 0 my $stem = shift;
373 0         0 my @list;
374 0         0 my $n = delete $ENV{"${stem}_n"};
375 0         0 my $val;
376 0         0 for $i ( 0 .. $n - 1 ) {
377 0         0 $val = delete $ENV{"${stem}_$i"};
378 0 0       0 $val =~ s/\\((\\)|0x(..))/ $2 ? $2 : pack('H2', $3) /ge;
  0         0  
379 0         0 push @list, $val;
380             }
381 0         0 @list;
382             } ## end sub get_list
383              
384             ###############################################################################
385             # no compile-time subroutine call allowed before this point #
386             ###############################################################################
387              
388             # this can run only after DB() and sub() are defined
389 12     12   107 use strict;
  12         36  
  12         15796  
390              
391             # Need this until we replace "save" with "save_vars" in Enbugger/trepan.pm
392 0     0 0 0 sub save { die "Remember to update Enbugger/trepan.pm" };
393              
394             # Like DB::save from perl5db.pl, but want to use another name to
395             # reduce prototype conflict of save $ vs none if we use perl5db.pl to
396             # debug Devel::Trepan.
397             sub save_vars() {
398 0     0 0 0 @DB::saved = ( $EVAL_ERROR, $ERRNO, $EXTENDED_OS_ERROR,
399             $OUTPUT_FIELD_SEPARATOR,
400             $INPUT_RECORD_SEPARATOR,
401             $OUTPUT_RECORD_SEPARATOR, $WARNING );
402              
403 0         0 $OUTPUT_FIELD_SEPARATOR = "";
404 0         0 $INPUT_RECORD_SEPARATOR = "\n";
405 0         0 $OUTPUT_RECORD_SEPARATOR = "";
406 0         0 $WARNING = 0; # warnings off
407             }
408              
409             sub catch {
410 0     0 0 0 @DB::_ = @_;
411 0         0 $DB::caller = [CORE::caller];
412             ($DB::package, $DB::filename, $DB::lineno, $DB::subroutine, $DB::hasargs,
413             $DB::wantarray, $DB::evaltext, $DB::is_require, $DB::hints, $DB::bitmask,
414             $DB::hinthash
415 0         0 ) = @{$DB::caller};
  0         0  
416              
417             # Set package namespace for running eval's in the user context.
418             # However this won't let them modify lexical variables, alas.
419 0         0 my $namespace_package = "package $DB::package;";
420              
421 0         0 $event = 'post-mortem';
422 0         0 $running = 0;
423 0         0 for my $c (@clients) {
424             # Now sit in an event loop until something sets $running
425 0         0 my $after_eval = 0;
426 0         0 do {
427             # Show display expresions
428 0         0 my $display_aref = $c->display_lists;
429 0         0 for my $disp (@$display_aref) {
430 0 0 0     0 next unless $disp && $disp->enabled;
431 0         0 my $opts = {
432             return_type => $disp->return_type,
433             namespace_package => $namespace_package,
434             fix_file_and_line => 1,
435             hide_position => 0};
436 0         0 my $eval_result = &DB::eval_with_return($disp->arg, $opts,
437             @DB::saved);
438 0         0 my $mess = sprintf("%d: $eval_result", $disp->number);
439 0         0 $c->output($mess);
440             }
441              
442 0 0       0 if (1 == $after_eval ) {
    0          
443 0         0 $event = 'after_eval';
444             } elsif (2 == $after_eval) {
445 0         0 $event = 'after_nest'
446             }
447              
448             # call client event loop; must not block
449 0         0 $c->idle($event, 0);
450 0         0 $after_eval = 0;
451 0 0 0     0 if ($running == 2 && defined($eval_str)) {
452             # client wants something eval-ed
453             # FIXME: turn into subroutine.
454              
455 0         0 my $opts = $eval_opts;
456 0         0 $opts->{namespace_package} = $namespace_package;
457              
458 0 0       0 if ('@' eq $opts->{return_type}) {
    0          
459 0         0 &DB::eval_with_return($eval_str, $opts, @DB::saved);
460             } elsif ('%' eq $opts->{return_type}) {
461 0         0 &DB::eval_with_return($eval_str, $opts, @DB::saved);
462             } else {
463 0         0 $eval_result =
464             &DB::eval_with_return($eval_str, $opts, @DB::saved);
465             }
466              
467 0         0 $after_eval = 1;
468 0         0 $running = 0;
469             }
470             } until $running;
471             }
472             }
473              
474             ####
475             #
476             # Client callable (read inheritable) methods defined after this point
477             #
478             ####
479              
480             sub register {
481 3     3 1 9 my $s = shift;
482             # $s = _clientname($s) if ref($s);
483 3         13 push @clients, $s;
484             }
485              
486             sub done {
487 0     0 1 0 my $s = shift;
488 0 0       0 $s = _clientname($s) if ref($s);
489 0         0 @clients = grep {$_ ne $s} @clients;
  0         0  
490 0         0 $s->cleanup;
491             # $running = 3 unless @clients;
492 0 0       0 exit(0) unless @clients;
493             }
494              
495             sub _clientname {
496 0     0   0 my $name = shift;
497 0         0 "$name" =~ /^(.+)=[A-Z]+\(.+\)$/;
498 0         0 return $1;
499             }
500              
501             sub step {
502 0     0 1 0 my $s = shift;
503 0         0 $DB::single = SINGLE_STEPPING_EVENT;
504 0         0 $DB::running = 1;
505             }
506              
507             # cont
508             # cont fn_or_line
509             # cont file line
510             #
511             sub cont {
512 0     0 0 0 my $s = shift;
513 0 0       0 if (scalar @_ > 0) {
514 0         0 my ($file, $line);
515 0 0       0 if (2 == scalar @_) {
516 0         0 print @_, "\n";
517 0         0 ($file, $line) = @_;
518             } else {
519 0         0 ($file, $line) = ($DB::filename, $_[0]);
520             }
521 0         0 my $brkpt = $s->set_tbreak($file, $line);
522 0 0       0 return 0 unless $brkpt;
523             }
524 0         0 for (my $i = 0; $i <= $#stack;) {
525 0 0       0 if (defined $stack[$i]) {
526 0         0 $stack[$i++] &= ~1 ;
527             } else {
528             # If Enbugger is used $stack[$i] might not be defined
529 0         0 $stack[$i++] = 0;
530             }
531             }
532 0         0 $DB::single = 0;
533 0         0 return $DB::running = 1;
534             }
535              
536             # stop before finishing the current subroutine
537             sub finish($;$$) {
538 0     0 0 0 my $s = shift;
539             # how many levels to get to DB sub?
540 0 0       0 my $count = scalar @_ >= 1 ? shift : 1;
541 0 0       0 my $scan_for_DB_sub = scalar @_ >= 1 ? shift : 1;
542              
543 0 0       0 if ($scan_for_DB_sub) {
544 0         0 my $i = 0;
545 0         0 while (my ($pkg, $file, $line, $fn) = CORE::caller($i++)) {
546             # Note: The function parameter of caller(), $fn, gives the
547             # function that was used rather than the function that the
548             # caller is currently in. Therefore, the implicitly line
549             # calling DB:DB is the one we want to stop at.
550 0 0 0     0 if ('DB::DB' eq $fn or ('DB' eq $pkg && 'DB' eq $fn)) {
      0        
551             # FIXME: This is hoaky. 4 is somehow how far off
552             # @stack is from caller.
553 0         0 $i -= 4;
554 0         0 last;
555             }
556             }
557 0         0 $count += $i;
558             }
559              
560 0         0 my $index = $#stack-$count;
561 0 0       0 $index = 0 if $index < 0;
562 0         0 $stack[$index] |= RETURN_EVENT;
563 0         0 $DB::single = RETURN_EVENT;
564 0         0 $DB::running = 1;
565             }
566              
567             sub return_value($)
568             {
569 0 0   0 0 0 if ('undef' eq $DB::return_type) {
    0          
570 0         0 return undef;
571             } elsif ('array' eq $DB::return_type) {
572 0         0 return @DB::return_value;
573             } else {
574 0         0 return $DB::return_value;
575             }
576             }
577              
578             sub return_type($)
579             {
580 0     0 0 0 $DB::return_type;
581             }
582              
583             sub _outputall {
584 0     0   0 my $c;
585 0         0 for $c (@clients) {
586 0         0 $c->output(@_);
587             }
588             }
589              
590             sub _warnall {
591 0     0   0 my $c;
592 0         0 for $c (@clients) {
593 0         0 $c->warning(@_);
594             }
595             }
596              
597             sub trace_toggle {
598 0     0 0 0 my $s = shift;
599 0         0 $DB::trace = !$DB::trace;
600             }
601              
602              
603             ####
604             # first argument is a filename whose subs will be returned
605             # if a filename is not supplied, all subs in the current
606             # filename are returned.
607             #
608             sub filesubs {
609 0     0 0 0 my $s = shift;
610 0         0 my $fname = shift;
611 0 0       0 $fname = $DB::filename unless $fname;
612 0         0 return grep { $DB::sub{$_} =~ /^$fname/ } keys %DB::sub;
  0         0  
613             }
614              
615             ####
616             # returns a list of all filenames that DB knows about
617             #
618             sub files {
619 0     0 0 0 my $s = shift;
620 0         0 my(@f) = grep(m|^_<|, keys %main::);
621 0         0 return map { substr($_,2) } @f;
  0         0  
622             }
623              
624             ####
625             # loadfile($file, $line)
626             #
627             sub loadfile {
628 0     0 0 0 my($file, $line) = @_;
629 0 0       0 if (!defined $main::{'_<' . $file}) {
630 0         0 my $try;
631 0 0       0 if (($try) = grep(m|^_<.*$file|, keys %main::)) {
632 0         0 $file = substr($try,2);
633             }
634             }
635 0 0       0 if (defined($main::{'_<' . $file})) {
636 0         0 my $c;
637             # _outputall("Loading file $file..");
638 0         0 *DB::dbline = "::_<$file";
639 0         0 $DB::filename = $file;
640 0         0 for $c (@clients) {
641             # print "2 ", $file, '|', $line, "\n";
642 0         0 $c->showfile($file, $line);
643             }
644 0         0 return $file;
645             }
646 0         0 return undef;
647             }
648              
649             #
650             # "pure virtual" methods
651             #
652              
653             sub skippkg {
654 9     9 0 20 my $s = shift;
655 9 50       46 push @skippkg, @_ if @_;
656             }
657              
658             sub evalcode {
659 0     0 1 0 my ($client, $expr) = @_;
660 0 0       0 if (defined $expr) {
661 0         0 $DB::running = 2; # hand over to DB() to evaluate in its context
662 0         0 $ineval->{$client} = $expr;
663             }
664 0         0 return $ineval->{$client};
665             }
666              
667             sub ready {
668 3     3 0 7 my $s = shift;
669 3         11 return $ready = 1;
670             }
671              
672       0 1   sub idle {}
673       0 1   sub cleanup {}
674       0 1   sub output {}
675       0 0   sub warning {}
676       0 0   sub showfile {}
677              
678             $SIG{'INT'} = \&DB::catch;
679              
680             1;
681             __END__
682              
683             =head1 NAME
684              
685             DB - programmatic interface to the Perl debugging API
686              
687             =head1 SYNOPSIS
688              
689             package CLIENT;
690             use DB;
691             @ISA = qw(DB);
692              
693             # these (inherited) methods can be called by the client
694              
695             CLIENT->register() # register a client package name
696             CLIENT->done() # de-register from the debugging API
697             CLIENT->skippkg('hide::hide') # ask DB not to stop in this package
698             CLIENT->cont([WHERE]) # run some more (until BREAK or another breakpt)
699             CLIENT->step() # single step
700             CLIENT->next() # step over
701             CLIENT->finish() # stop before finishing the current subroutine
702             CLIENT->ready() # call when client setup is done
703             CLIENT->trace_toggle() # toggle subroutine call trace mode
704             CLIENT->subs([SUBS]) # return subroutine information
705             CLIENT->files() # return list of all files known to DB
706             CLIENT->loadfile(FILE,LINE) # load a file and let other clients know
707             CLIENT->set_break([WHERE],[COND])
708             CLIENT->set_tbreak([WHERE])
709             CLIENT->clr_breaks([LIST])
710             CLIENT->set_action(WHERE,ACTION)
711             CLIENT->clr_actions([LIST])
712             CLIENT->evalcode(STRING) # eval STRING in executing code's context
713              
714             # These methods you should define; They will be called by the DB
715             # when appropriate. The stub versions provided do nothing. You should
716             # Write your routine so that it doesn't block.
717              
718             CLIENT->init() # called when debug API inits itself
719             CLIENT->idle(BOOL, EVENT, ARGS) # while stopped (can be a client event loop)
720             CLIENT->cleanup() # just before exit
721             CLIENT->output(STRING) # called to print any output that API must show
722             CLIENT->warning(STRING) # called to print any warning output that API
723             # must show
724             CLIENT->showfile(FILE,LINE) # called to show file and line before idling
725              
726             =head1 DESCRIPTION
727              
728             Perl debug information is frequently required not just by debuggers,
729             but also by modules that need some "special" information to do their
730             job properly, like profilers.
731              
732             This module abstracts and provides all of the hooks into Perl internal
733             debugging functionality, so that various implementations of Perl debuggers
734             (or packages that want to simply get at the "privileged" debugging data)
735             can all benefit from the development of this common code. Currently used
736             by Swat, the perl/Tk GUI debugger.
737              
738             Note that multiple "front-ends" can latch into this debugging API
739             simultaneously. This is intended to facilitate things like
740             debugging with a command line and GUI at the same time, debugging
741             debuggers etc. [Sounds nice, but this needs some serious support -- GSAR]
742              
743             In particular, this API does B<not> provide the following functions:
744              
745             =over 4
746              
747             =item *
748              
749             data display
750              
751             =item *
752              
753             command processing
754              
755             =item *
756              
757             command alias management
758              
759             =item *
760              
761             user interface (tty or graphical)
762              
763             =back
764              
765             These are intended to be services performed by the clients of this API.
766              
767             This module attempts to be squeaky clean w.r.t C<use strict;> and when
768             warnings are enabled.
769              
770             =head2 API Methods
771              
772             The following are methods in the DB base class. A client must
773             access these methods by inheritance (*not* by calling them directly),
774             since the API keeps track of clients through the inheritance
775             mechanism.
776              
777             =over 8
778              
779             =item CLIENT->register()
780              
781             register a client object/package
782              
783             =item CLIENT->evalcode(STRING)
784              
785             eval STRING in executing code context
786              
787             =item CLIENT->skippkg('D::hide')
788              
789             ask DB not to stop in these packages
790              
791             =item CLIENT->cont()
792              
793             continue some more (until a breakpoint is reached)
794              
795             =item CLIENT->step()
796              
797             single step
798              
799             =item CLIENT->next()
800              
801             step over
802              
803             =item CLIENT->done()
804              
805             de-register from the debugging API
806              
807             =back
808              
809             =head2 Client Callback Methods
810              
811             The following "virtual" methods can be defined by the client. They will
812             be called by the API at appropriate points. Note that unless specified
813             otherwise, the debug API only defines empty, non-functional default versions
814             of these methods.
815              
816             =over 8
817              
818             =item CLIENT->init()
819              
820             Called after debug API inits itself.
821              
822             =item CLIENT->idle(BOOLEAN, EVENT, ARGS)
823              
824             Called while stopped (can be a client event loop or REPL). If called
825             after the idle program requested an eval to be performed, BOOLEAN will be
826             true. False otherwise. See evalcode below. ARGS are any
827              
828             =item CLIENT->evalcode(STRING)
829              
830             Usually inherited from DB package. Ask for a STRING to be C<eval>-ed
831             in executing code context.
832              
833             In order to evaluate properly, control has to be passed back to the DB
834             subroutine. Suppose you would like your C<idle> program to do this:
835              
836             until $done {
837             $command = read input
838             if $command is a valid debugger command,
839             run it
840             else
841             evaluate it via CLIENT->evalcode($command) and print
842             the results.
843             }
844              
845             Due to the limitation of Perl, the above is not sufficient. You have to
846             break out of the B<until> to get back to C<DB::sub> to have the eval run.
847             After that's done, C<DB::sub> will call idle again, from which you can
848             then retrieve the results.
849              
850             One other important item to note is that one can only evaluation reliably
851             current (most recent) frame and not frames further down the stack.
852              
853             That's probably why the stock Perl debugger doesn't have
854             frame-switching commands.
855              
856             =item CLIENT->cleanup()
857              
858             Called just before exit.
859              
860             =item CLIENT->output(LIST)
861              
862             Called when API must show a message (warnings, errors etc.).
863              
864              
865             =back
866              
867              
868             =head1 BUGS
869              
870             The interface defined by this module is missing a number of Perl's
871             debugging functionality. As such, this interface is subject to
872             (possibly incompatible) change.
873              
874             =head1 AUTHOR
875              
876             Gurusamy Sarathy gsar@activestate.com
877              
878             This code heavily adapted from an early version of perl5db.pl attributable
879             to Larry Wall and the Perl Porters.
880              
881             Further modifications by R. Bernstein rocky@cpan.org
882              
883             =cut