forked from Perl/perl5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathperl5db.pl
10380 lines (7846 loc) · 310 KB
/
perl5db.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
=head1 NAME
perl5db.pl - the perl debugger
=head1 SYNOPSIS
perl -d your_Perl_script
=head1 DESCRIPTION
C<perl5db.pl> is the perl debugger. It is loaded automatically by Perl when
you invoke a script with C<perl -d>. This documentation tries to outline the
structure and services provided by C<perl5db.pl>, and to describe how you
can use them.
=head1 GENERAL NOTES
The debugger can look pretty forbidding to many Perl programmers. There are
a number of reasons for this, many stemming out of the debugger's history.
When the debugger was first written, Perl didn't have a lot of its nicer
features - no references, no lexical variables, no closures, no object-oriented
programming. So a lot of the things one would normally have done using such
features was done using global variables, globs and the C<local()> operator
in creative ways.
Some of these have survived into the current debugger; a few of the more
interesting and still-useful idioms are noted in this section, along with notes
on the comments themselves.
=head2 Why not use more lexicals?
Experienced Perl programmers will note that the debugger code tends to use
mostly package globals rather than lexically-scoped variables. This is done
to allow a significant amount of control of the debugger from outside the
debugger itself.
Unfortunately, though the variables are accessible, they're not well
documented, so it's generally been a decision that hasn't made a lot of
difference to most users. Where appropriate, comments have been added to
make variables more accessible and usable, with the understanding that these
I<are> debugger internals, and are therefore subject to change. Future
development should probably attempt to replace the globals with a well-defined
API, but for now, the variables are what we've got.
=head2 Automated variable stacking via C<local()>
As you may recall from reading C<perlfunc>, the C<local()> operator makes a
temporary copy of a variable in the current scope. When the scope ends, the
old copy is restored. This is often used in the debugger to handle the
automatic stacking of variables during recursive calls:
sub foo {
local $some_global++;
# Do some stuff, then ...
return;
}
What happens is that on entry to the subroutine, C<$some_global> is localized,
then altered. When the subroutine returns, Perl automatically undoes the
localization, restoring the previous value. Voila, automatic stack management.
The debugger uses this trick a I<lot>. Of particular note is C<DB::eval>,
which lets the debugger get control inside of C<eval>'ed code. The debugger
localizes a saved copy of C<$@> inside the subroutine, which allows it to
keep C<$@> safe until it C<DB::eval> returns, at which point the previous
value of C<$@> is restored. This makes it simple (well, I<simpler>) to keep
track of C<$@> inside C<eval>s which C<eval> other C<eval's>.
In any case, watch for this pattern. It occurs fairly often.
=head2 The C<^> trick
This is used to cleverly reverse the sense of a logical test depending on
the value of an auxiliary variable. For instance, the debugger's C<S>
(search for subroutines by pattern) allows you to negate the pattern
like this:
# Find all non-'foo' subs:
S !/foo/
Boolean algebra states that the truth table for XOR looks like this:
=over 4
=item * 0 ^ 0 = 0
(! not present and no match) --> false, don't print
=item * 0 ^ 1 = 1
(! not present and matches) --> true, print
=item * 1 ^ 0 = 1
(! present and no match) --> true, print
=item * 1 ^ 1 = 0
(! present and matches) --> false, don't print
=back
As you can see, the first pair applies when C<!> isn't supplied, and
the second pair applies when it is. The XOR simply allows us to
compact a more complicated if-then-elseif-else into a more elegant
(but perhaps overly clever) single test. After all, it needed this
explanation...
=head2 FLAGS, FLAGS, FLAGS
There is a certain C programming legacy in the debugger. Some variables,
such as C<$single>, C<$trace>, and C<$frame>, have I<magical> values composed
of 1, 2, 4, etc. (powers of 2) OR'ed together. This allows several pieces
of state to be stored independently in a single scalar.
A test like
if ($scalar & 4) ...
is checking to see if the appropriate bit is on. Since each bit can be
"addressed" independently in this way, C<$scalar> is acting sort of like
an array of bits. Obviously, since the contents of C<$scalar> are just a
bit-pattern, we can save and restore it easily (it will just look like
a number).
The problem, is of course, that this tends to leave magic numbers scattered
all over your program whenever a bit is set, cleared, or checked. So why do
it?
=over 4
=item *
First, doing an arithmetical or bitwise operation on a scalar is
just about the fastest thing you can do in Perl: C<use constant> actually
creates a subroutine call, and array and hash lookups are much slower. Is
this over-optimization at the expense of readability? Possibly, but the
debugger accesses these variables a I<lot>. Any rewrite of the code will
probably have to benchmark alternate implementations and see which is the
best balance of readability and speed, and then document how it actually
works.
=item *
Second, it's very easy to serialize a scalar number. This is done in
the restart code; the debugger state variables are saved in C<%ENV> and then
restored when the debugger is restarted. Having them be just numbers makes
this trivial.
=item *
Third, some of these variables are being shared with the Perl core
smack in the middle of the interpreter's execution loop. It's much faster for
a C program (like the interpreter) to check a bit in a scalar than to access
several different variables (or a Perl array).
=back
=head2 What are those C<XXX> comments for?
Any comment containing C<XXX> means that the comment is either somewhat
speculative - it's not exactly clear what a given variable or chunk of
code is doing, or that it is incomplete - the basics may be clear, but the
subtleties are not completely documented.
Send in a patch if you can clear up, fill out, or clarify an C<XXX>.
=head1 DATA STRUCTURES MAINTAINED BY CORE
There are a number of special data structures provided to the debugger by
the Perl interpreter.
The array C<@{$main::{'_<'.$filename}}> (aliased locally to C<@dbline>
via glob assignment) contains the text from C<$filename>, with each
element corresponding to a single line of C<$filename>. Additionally,
breakable lines will be dualvars with the numeric component being the
memory address of a COP node. Non-breakable lines are dualvar to 0.
The hash C<%{'_<'.$filename}> (aliased locally to C<%dbline> via glob
assignment) contains breakpoints and actions. The keys are line numbers;
you can set individual values, but not the whole hash. The Perl interpreter
uses this hash to determine where breakpoints have been set. Any true value is
considered to be a breakpoint; C<perl5db.pl> uses C<$break_condition\0$action>.
Values are magical in numeric context: 1 if the line is breakable, 0 if not.
The scalar C<${"_<$filename"}> simply contains the string C<$filename>.
This is also the case for evaluated strings that contain subroutines, or
which are currently being executed. The $filename for C<eval>ed strings looks
like C<(eval 34)>.
=head1 DEBUGGER STARTUP
When C<perl5db.pl> starts, it reads an rcfile (C<perl5db.ini> for
non-interactive sessions, C<.perldb> for interactive ones) that can set a number
of options. In addition, this file may define a subroutine C<&afterinit>
that will be executed (in the debugger's context) after the debugger has
initialized itself.
Next, it checks the C<PERLDB_OPTS> environment variable and treats its
contents as the argument of a C<o> command in the debugger.
=head2 STARTUP-ONLY OPTIONS
The following options can only be specified at startup.
To set them in your rcfile, add a call to
C<&parse_options("optionName=new_value")>.
=over 4
=item * TTY
the TTY to use for debugging i/o.
=item * noTTY
if set, goes in NonStop mode. On interrupt, if TTY is not set,
uses the value of noTTY or F<$HOME/.perldbtty$$> to find TTY using
Term::Rendezvous. Current variant is to have the name of TTY in this
file.
=item * ReadLine
if false, a dummy ReadLine is used, so you can debug
ReadLine applications.
=item * NonStop
if true, no i/o is performed until interrupt.
=item * LineInfo
file or pipe to print line number info to. If it is a
pipe, a short "emacs like" message is used.
=item * RemotePort
host:port to connect to on remote host for remote debugging.
=item * HistFile
file to store session history to. There is no default and so no
history file is written unless this variable is explicitly set.
=item * HistSize
number of commands to store to the file specified in C<HistFile>.
Default is 100.
=back
=head3 SAMPLE RCFILE
&parse_options("NonStop=1 LineInfo=db.out");
sub afterinit { $trace = 1; }
The script will run without human intervention, putting trace
information into C<db.out>. (If you interrupt it, you had better
reset C<LineInfo> to something I<interactive>!)
=head1 INTERNALS DESCRIPTION
=head2 DEBUGGER INTERFACE VARIABLES
Perl supplies the values for C<%sub>. It effectively inserts
a C<&DB::DB();> in front of each place that can have a
breakpoint. At each subroutine call, it calls C<&DB::sub> with
C<$DB::sub> set to the called subroutine. It also inserts a C<BEGIN
{require 'perl5db.pl'}> before the first line.
After each C<require>d file is compiled, but before it is executed, a
call to C<&DB::postponed($main::{'_<'.$filename})> is done. C<$filename>
is the expanded name of the C<require>d file (as found via C<%INC>).
=head3 IMPORTANT INTERNAL VARIABLES
=head4 C<$CreateTTY>
Used to control when the debugger will attempt to acquire another TTY to be
used for input.
=over
=item * 1 - on C<fork()>
=item * 2 - debugger is started inside debugger
=item * 4 - on startup
=back
=head4 C<$doret>
The value -2 indicates that no return value should be printed.
Any other positive value causes C<DB::sub> to print return values.
=head4 C<$evalarg>
The item to be eval'ed by C<DB::eval>. Used to prevent messing with the current
contents of C<@_> when C<DB::eval> is called.
=head4 C<$frame>
Determines what messages (if any) will get printed when a subroutine (or eval)
is entered or exited.
=over 4
=item * 0 - No enter/exit messages
=item * 1 - Print I<entering> messages on subroutine entry
=item * 2 - Adds exit messages on subroutine exit. If no other flag is on, acts like 1+2.
=item * 4 - Extended messages: C<< <in|out> I<context>=I<fully-qualified sub name> from I<file>:I<line> >>. If no other flag is on, acts like 1+4.
=item * 8 - Adds parameter information to messages, and overloaded stringify and tied FETCH is enabled on the printed arguments. Ignored if C<4> is not on.
=item * 16 - Adds C<I<context> return from I<subname>: I<value>> messages on subroutine/eval exit. Ignored if C<4> is not on.
=back
To get everything, use C<$frame=30> (or C<o f=30> as a debugger command).
The debugger internally juggles the value of C<$frame> during execution to
protect external modules that the debugger uses from getting traced.
=head4 C<$level>
Tracks current debugger nesting level. Used to figure out how many
C<E<lt>E<gt>> pairs to surround the line number with when the debugger
outputs a prompt. Also used to help determine if the program has finished
during command parsing.
=head4 C<$onetimeDump>
Controls what (if anything) C<DB::eval()> will print after evaluating an
expression.
=over 4
=item * C<undef> - don't print anything
=item * C<dump> - use C<dumpvar.pl> to display the value returned
=item * C<methods> - print the methods callable on the first item returned
=back
=head4 C<$onetimeDumpDepth>
Controls how far down C<dumpvar.pl> will go before printing C<...> while
dumping a structure. Numeric. If C<undef>, print all levels.
=head4 C<$signal>
Used to track whether or not an C<INT> signal has been detected. C<DB::DB()>,
which is called before every statement, checks this and puts the user into
command mode if it finds C<$signal> set to a true value.
=head4 C<$single>
Controls behavior during single-stepping. Stacked in C<@stack> on entry to
each subroutine; popped again at the end of each subroutine.
=over 4
=item * 0 - run continuously.
=item * 1 - single-step, go into subs. The C<s> command.
=item * 2 - single-step, don't go into subs. The C<n> command.
=item * 4 - print current sub depth (turned on to force this when C<too much
recursion> occurs.
=back
=head4 C<$trace>
Controls the output of trace information.
=over 4
=item * 1 - The C<t> command was entered to turn on tracing (every line executed is printed)
=item * 2 - watch expressions are active
=item * 4 - user defined a C<watchfunction()> in C<afterinit()>
=back
=head4 C<$slave_editor>
1 if C<LINEINFO> was directed to a pipe; 0 otherwise.
=head4 C<@cmdfhs>
Stack of filehandles that C<DB::readline()> will read commands from.
Manipulated by the debugger's C<source> command and C<DB::readline()> itself.
=head4 C<@dbline>
Local alias to the magical line array, C<@{$main::{'_<'.$filename}}> ,
supplied by the Perl interpreter to the debugger. Contains the source.
=head4 C<@old_watch>
Previous values of watch expressions. First set when the expression is
entered; reset whenever the watch expression changes.
=head4 C<@saved>
Saves important globals (C<$@>, C<$!>, C<$^E>, C<$,>, C<$/>, C<$\>, C<$^W>)
so that the debugger can substitute safe values while it's running, and
restore them when it returns control.
=head4 C<@stack>
Saves the current value of C<$single> on entry to a subroutine.
Manipulated by the C<c> command to turn off tracing in all subs above the
current one.
=head4 C<@to_watch>
The 'watch' expressions: to be evaluated before each line is executed.
=head4 C<@typeahead>
The typeahead buffer, used by C<DB::readline>.
=head4 C<%alias>
Command aliases. Stored as character strings to be substituted for a command
entered.
=head4 C<%break_on_load>
Keys are file names, values are 1 (break when this file is loaded) or undef
(don't break when it is loaded).
=head4 C<%dbline>
Keys are line numbers, values are C<condition\0action>. If used in numeric
context, values are 0 if not breakable, 1 if breakable, no matter what is
in the actual hash entry.
=head4 C<%had_breakpoints>
Keys are file names; values are bitfields:
=over 4
=item * 1 - file has a breakpoint in it.
=item * 2 - file has an action in it.
=back
A zero or undefined value means this file has neither.
=head4 C<%option>
Stores the debugger options. These are character string values.
=head4 C<%postponed>
Saves breakpoints for code that hasn't been compiled yet.
Keys are subroutine names, values are:
=over 4
=item * C<compile> - break when this sub is compiled
=item * C<< break +0 if <condition> >> - break (conditionally) at the start of this routine. The condition will be '1' if no condition was specified.
=back
=head4 C<%postponed_file>
This hash keeps track of breakpoints that need to be set for files that have
not yet been compiled. Keys are filenames; values are references to hashes.
Each of these hashes is keyed by line number, and its values are breakpoint
definitions (C<condition\0action>).
=head1 DEBUGGER INITIALIZATION
The debugger's initialization actually jumps all over the place inside this
package. This is because there are several BEGIN blocks (which of course
execute immediately) spread through the code. Why is that?
The debugger needs to be able to change some things and set some things up
before the debugger code is compiled; most notably, the C<$deep> variable that
C<DB::sub> uses to tell when a program has recursed deeply. In addition, the
debugger has to turn off warnings while the debugger code is compiled, but then
restore them to their original setting before the program being debugged begins
executing.
The first C<BEGIN> block simply turns off warnings by saving the current
setting of C<$^W> and then setting it to zero. The second one initializes
the debugger variables that are needed before the debugger begins executing.
The third one puts C<$^X> back to its former value.
We'll detail the second C<BEGIN> block later; just remember that if you need
to initialize something before the debugger starts really executing, that's
where it has to go.
=cut
package DB;
use strict;
use Cwd ();
my $_initial_cwd;
BEGIN {eval 'use IO::Handle'}; # Needed for flush only? breaks under miniperl
BEGIN {
require feature;
$^V =~ /^v(\d+\.\d+)/;
feature->import(":$1");
$_initial_cwd = Cwd::getcwd();
}
# Debugger for Perl 5.00x; perl5db.pl patch level:
use vars qw($VERSION $header);
# bump to X.XX in blead, only use X.XX_XX in maint
$VERSION = '1.55';
$header = "perl5db.pl version $VERSION";
=head1 DEBUGGER ROUTINES
=head2 C<DB::eval()>
This function replaces straight C<eval()> inside the debugger; it simplifies
the process of evaluating code in the user's context.
The code to be evaluated is passed via the package global variable
C<$DB::evalarg>; this is done to avoid fiddling with the contents of C<@_>.
Before we do the C<eval()>, we preserve the current settings of C<$trace>,
C<$single>, C<$^D> and C<$usercontext>. The latter contains the
preserved values of C<$@>, C<$!>, C<$^E>, C<$,>, C<$/>, C<$\>, C<$^W> and the
user's current package, grabbed when C<DB::DB> got control. This causes the
proper context to be used when the eval is actually done. Afterward, we
restore C<$trace>, C<$single>, and C<$^D>.
Next we need to handle C<$@> without getting confused. We save C<$@> in a
local lexical, localize C<$saved[0]> (which is where C<save()> will put
C<$@>), and then call C<save()> to capture C<$@>, C<$!>, C<$^E>, C<$,>,
C<$/>, C<$\>, and C<$^W>) and set C<$,>, C<$/>, C<$\>, and C<$^W> to values
considered sane by the debugger. If there was an C<eval()> error, we print
it on the debugger's output. If C<$onetimedump> is defined, we call
C<dumpit> if it's set to 'dump', or C<methods> if it's set to
'methods'. Setting it to something else causes the debugger to do the eval
but not print the result - handy if you want to do something else with it
(the "watch expressions" code does this to get the value of the watch
expression but not show it unless it matters).
In any case, we then return the list of output from C<eval> to the caller,
and unwinding restores the former version of C<$@> in C<@saved> as well
(the localization of C<$saved[0]> goes away at the end of this scope).
=head3 Parameters and variables influencing execution of DB::eval()
C<DB::eval> isn't parameterized in the standard way; this is to keep the
debugger's calls to C<DB::eval()> from mucking with C<@_>, among other things.
The variables listed below influence C<DB::eval()>'s execution directly.
=over 4
=item C<$evalarg> - the thing to actually be eval'ed
=item C<$trace> - Current state of execution tracing
=item C<$single> - Current state of single-stepping
=item C<$onetimeDump> - what is to be displayed after the evaluation
=item C<$onetimeDumpDepth> - how deep C<dumpit()> should go when dumping results
=back
The following variables are altered by C<DB::eval()> during its execution. They
are "stacked" via C<local()>, enabling recursive calls to C<DB::eval()>.
=over 4
=item C<@res> - used to capture output from actual C<eval>.
=item C<$otrace> - saved value of C<$trace>.
=item C<$osingle> - saved value of C<$single>.
=item C<$od> - saved value of C<$^D>.
=item C<$saved[0]> - saved value of C<$@>.
=item $\ - for output of C<$@> if there is an evaluation error.
=back
=head3 The problem of lexicals
The context of C<DB::eval()> presents us with some problems. Obviously,
we want to be 'sandboxed' away from the debugger's internals when we do
the eval, but we need some way to control how punctuation variables and
debugger globals are used.
We can't use local, because the code inside C<DB::eval> can see localized
variables; and we can't use C<my> either for the same reason. The code
in this routine compromises and uses C<my>.
After this routine is over, we don't have user code executing in the debugger's
context, so we can use C<my> freely.
=cut
############################################## Begin lexical danger zone
# 'my' variables used here could leak into (that is, be visible in)
# the context that the code being evaluated is executing in. This means that
# the code could modify the debugger's variables.
#
# Fiddling with the debugger's context could be Bad. We insulate things as
# much as we can.
use vars qw(
@args
%break_on_load
$CommandSet
$CreateTTY
$DBGR
@dbline
$dbline
%dbline
$dieLevel
$filename
$histfile
$histsize
$IN
$inhibit_exit
@ini_INC
$ini_warn
$maxtrace
$od
@options
$osingle
$otrace
$pager
$post
%postponed
$prc
$pre
$pretype
$psh
@RememberOnROptions
$remoteport
@res
$rl
@saved
$signalLevel
$sub
$term
$usercontext
$warnLevel
);
our (
@cmdfhs,
$evalarg,
$frame,
$hist,
$ImmediateStop,
$line,
$onetimeDump,
$onetimedumpDepth,
%option,
$OUT,
$packname,
$signal,
$single,
$start,
%sub,
$subname,
$trace,
$window,
);
# Used to save @ARGV and extract any debugger-related flags.
use vars qw(@ARGS);
# Used to prevent multiple entries to diesignal()
# (if for instance diesignal() itself dies)
use vars qw($panic);
# Used to prevent the debugger from running nonstop
# after a restart
our ($second_time);
sub _calc_usercontext {
my ($package) = @_;
# Cancel strict completely for the evaluated code, so the code
# the user evaluates won't be affected by it. (Shlomi Fish)
return 'no strict; ($@, $!, $^E, $,, $/, $\, $^W) = @DB::saved;'
. "package $package;"; # this won't let them modify, alas
}
sub eval {
# 'my' would make it visible from user code
# but so does local! --tchrist
# Remember: this localizes @DB::res, not @main::res.
local @res;
{
# Try to keep the user code from messing with us. Save these so that
# even if the eval'ed code changes them, we can put them back again.
# Needed because the user could refer directly to the debugger's
# package globals (and any 'my' variables in this containing scope)
# inside the eval(), and we want to try to stay safe.
local $otrace = $trace;
local $osingle = $single;
local $od = $^D;
# Untaint the incoming eval() argument.
{ ($evalarg) = $evalarg =~ /(.*)/s; }
# $usercontext built in DB::DB near the comment
# "set up the context for DB::eval ..."
# Evaluate and save any results.
@res = eval "$usercontext $evalarg;\n"; # '\n' for nice recursive debug
# Restore those old values.
$trace = $otrace;
$single = $osingle;
$^D = $od;
}
# Save the current value of $@, and preserve it in the debugger's copy
# of the saved precious globals.
my $at = $@;
# Since we're only saving $@, we only have to localize the array element
# that it will be stored in.
local $saved[0]; # Preserve the old value of $@
eval { &DB::save };
# Now see whether we need to report an error back to the user.
if ($at) {
local $\ = '';
print $OUT $at;
}
# Display as required by the caller. $onetimeDump and $onetimedumpDepth
# are package globals.
elsif ($onetimeDump) {
if ( $onetimeDump eq 'dump' ) {
local $option{dumpDepth} = $onetimedumpDepth
if defined $onetimedumpDepth;
dumpit( $OUT, \@res );
}
elsif ( $onetimeDump eq 'methods' ) {
methods( $res[0] );
}
} ## end elsif ($onetimeDump)
@res;
} ## end sub eval
############################################## End lexical danger zone
# After this point it is safe to introduce lexicals.
# The code being debugged will be executing in its own context, and
# can't see the inside of the debugger.
#
# However, one should not overdo it: leave as much control from outside as
# possible. If you make something a lexical, it's not going to be addressable
# from outside the debugger even if you know its name.
# This file is automatically included if you do perl -d.
# It's probably not useful to include this yourself.
#
# Before venturing further into these twisty passages, it is
# wise to read the perldebguts man page or risk the ire of dragons.
#
# (It should be noted that perldebguts will tell you a lot about
# the underlying mechanics of how the debugger interfaces into the
# Perl interpreter, but not a lot about the debugger itself. The new
# comments in this code try to address this problem.)
# Note that no subroutine call is possible until &DB::sub is defined
# (for subroutines defined outside of the package DB). In fact the same is
# true if $deep is not defined.
# Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich)
# modified Perl debugger, to be run from Emacs in perldb-mode
# Ray Lischner (uunet!mntgfx!lisch) as of 5 Nov 1990
# Johan Vromans -- upgrade to 4.0 pl 10
# Ilya Zakharevich -- patches after 5.001 (and some before ;-)
########################################################################
=head1 DEBUGGER INITIALIZATION
The debugger starts up in phases.
=head2 BASIC SETUP
First, it initializes the environment it wants to run in: turning off
warnings during its own compilation, defining variables which it will need
to avoid warnings later, setting itself up to not exit when the program
terminates, and defaulting to printing return values for the C<r> command.
=cut
# Needed for the statement after exec():
#
# This BEGIN block is simply used to switch off warnings during debugger
# compilation. Probably it would be better practice to fix the warnings,
# but this is how it's done at the moment.
BEGIN {
$ini_warn = $^W;
$^W = 0;
} # Switch compilation warnings off until another BEGIN.
local ($^W) = 0; # Switch run-time warnings off during init.
=head2 THREADS SUPPORT
If we are running under a threaded Perl, we require threads and threads::shared
if the environment variable C<PERL5DB_THREADED> is set, to enable proper
threaded debugger control. C<-dt> can also be used to set this.
Each new thread will be announced and the debugger prompt will always inform
you of each new thread created. It will also indicate the thread id in which
we are currently running within the prompt like this:
[tid] DB<$i>
Where C<[tid]> is an integer thread id and C<$i> is the familiar debugger
command prompt. The prompt will show: C<[0]> when running under threads, but
not actually in a thread. C<[tid]> is consistent with C<gdb> usage.
While running under threads, when you set or delete a breakpoint (etc.), this
will apply to all threads, not just the currently running one. When you are
in a currently executing thread, you will stay there until it completes. With
the current implementation it is not currently possible to hop from one thread
to another.
The C<e> and C<E> commands are currently fairly minimal - see C<h e> and C<h E>.
Note that threading support was built into the debugger as of Perl version
C<5.8.6> and debugger version C<1.2.8>.
=cut
BEGIN {
# ensure we can share our non-threaded variables or no-op
if ($ENV{PERL5DB_THREADED}) {
require threads;
require threads::shared;
import threads::shared qw(share);
$DBGR;
share(\$DBGR);
lock($DBGR);
print "Threads support enabled\n";
} else {
*lock = sub(*) {};
*share = sub(\[$@%]) {};
}
}
# These variables control the execution of 'dumpvar.pl'.
{
package dumpvar;
use vars qw(
$hashDepth
$arrayDepth
$dumpDBFiles
$dumpPackages
$quoteHighBit
$printUndef
$globPrint
$usageOnly
);
}
# used to control die() reporting in diesignal()
{
package Carp;
use vars qw($CarpLevel);
}
# without threads, $filename is not defined until DB::DB is called
share($main::{'_<'.$filename}) if defined $filename;
# Command-line + PERLLIB:
# Save the contents of @INC before they are modified elsewhere.
@ini_INC = @INC;
# This was an attempt to clear out the previous values of various
# trapped errors. Apparently it didn't help. XXX More info needed!
# $prevwarn = $prevdie = $prevbus = $prevsegv = ''; # Does not help?!
# We set these variables to safe values. We don't want to blindly turn
# off warnings, because other packages may still want them.
$trace = $signal = $single = 0; # Uninitialized warning suppression
# (local $^W cannot help - other packages!).
# Default to not exiting when program finishes; print the return
# value when the 'r' command is used to return from a subroutine.
$inhibit_exit = $option{PrintRet} = 1;
use vars qw($trace_to_depth);
# Default to 1E9 so it won't be limited to a certain recursion depth.
$trace_to_depth = 1E9;
=head1 OPTION PROCESSING
The debugger's options are actually spread out over the debugger itself and
C<dumpvar.pl>; some of these are variables to be set, while others are
subs to be called with a value. To try to make this a little easier to
manage, the debugger uses a few data structures to define what options
are legal and how they are to be processed.
First, the C<@options> array defines the I<names> of all the options that
are to be accepted.
=cut
@options = qw(
CommandSet HistFile HistSize
hashDepth arrayDepth dumpDepth
DumpDBFiles DumpPackages DumpReused
compactDump veryCompact quote
HighBit undefPrint globPrint
PrintRet UsageOnly frame
AutoTrace TTY noTTY
ReadLine NonStop LineInfo
maxTraceLen recallCommand ShellBang
pager tkRunning ornaments
signalLevel warnLevel dieLevel
inhibit_exit ImmediateStop bareStringify
CreateTTY RemotePort windowSize
DollarCaretP
);
@RememberOnROptions = qw(DollarCaretP);
=pod
Second, C<optionVars> lists the variables that each option uses to save its
state.
=cut
use vars qw(%optionVars);
%optionVars = (
hashDepth => \$dumpvar::hashDepth,
arrayDepth => \$dumpvar::arrayDepth,
CommandSet => \$CommandSet,
DumpDBFiles => \$dumpvar::dumpDBFiles,
DumpPackages => \$dumpvar::dumpPackages,
DumpReused => \$dumpvar::dumpReused,
HighBit => \$dumpvar::quoteHighBit,
undefPrint => \$dumpvar::printUndef,
globPrint => \$dumpvar::globPrint,
UsageOnly => \$dumpvar::usageOnly,
CreateTTY => \$CreateTTY,
bareStringify => \$dumpvar::bareStringify,
frame => \$frame,
AutoTrace => \$trace,
inhibit_exit => \$inhibit_exit,
maxTraceLen => \$maxtrace,
ImmediateStop => \$ImmediateStop,
RemotePort => \$remoteport,
windowSize => \$window,
HistFile => \$histfile,
HistSize => \$histsize,
);
=pod
Third, C<%optionAction> defines the subroutine to be called to process each
option.
=cut
use vars qw(%optionAction);
%optionAction = (