File Coverage

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