|
|
1.1 root 1: .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n
2: .if n .po 1.25i
3: .if t .po 1.0i
4: .hy 14
5: .de hd
6: 'sp 3
7: 'if \\n%-1 'tl ''- % -''
8: 'sp 2
9: .if \\n(vq>0 .xj
10: .nr vq 0
11: 'ns
12: ..
13: .de fo
14: .nr vk 0
15: .nr dn 0
16: .nr wf \\n(.pu-\\n(nlu-\\n(vmu-1v
17: .if \\n(vs>0 .if \\n(wf>0 .xn
18: .if \\n(vs>0 .if \\n(wf<=0 .xo
19: .ch fo -\\n(vmu
20: .nr vs 0
21: .nr vo \\n(vmu
22: 'bp
23: ..
24: .de fe
25: .br
26: .di
27: .ev
28: .if \\n(vs=1 .nr dn +1v
29: .nr vo +\\n(dnu
30: .nr dn 0
31: .if \\n(vou>=\\n(.pu-\\n(nlu-.5v .nr vo \\n(.pu-\\n(nlu-.5v
32: .if \\n(vou<\\n(vmu .nr vo \\n(vmu
33: .ch fo -\\n(vou
34: ..
35: .de xj
36: .nr vs 1
37: .nr vn 1
38: .di
39: .ev 1
40: .da zb
41: .ns
42: .za
43: .zc
44: .fe
45: .rm za
46: .rm zc
47: ..
48: .de xn
49: .ev 1
50: 'in 0
51: 'ti 0
52: .ie \\n(vn \l\|6.0i\(ru\|
53: .el \l\|15\(ru\|
54: .nr vn 0
55: .br
56: .ns
57: .zb
58: .br
59: .di
60: .rm zb
61: .nr vq \\n(dnu
62: .nr dn 0
63: .nr vs 0
64: .ev
65: ..
66: .de xo
67: .ev 1
68: .di zc
69: .zb
70: .br
71: .di
72: .rm zb
73: .nr vq \\n(dnu
74: .nr dn 0
75: .nr vs 0
76: .nr vn 1
77: .ev
78: ..
79: .de xp
80: .di za
81: ..
82: .nr vm 6v
83: .nr vo \n(vmu
84: .wh 0 hd
85: .wh -1.0i fo
86: .ch fo 15i
87: .wh -\n(vmu xp
88: .ch fo -\n(vmu
89: .if n .ll 6.5i
90: .if t .ll 6.0i
91: .if n .lt 6.5i
92: .if t .lt 6.0i
93: .ev 1
94: .if n .ll 6.5i
95: .if t .ll 6.0i
96: .if n .lt 6.5i
97: .if t .lt 6.0i
98: .ev
99: .nr ap 1
100: .af ap A
101: .sp 6
102: .ps +2
103: .ce
104: \fBAn Introduction to Pdx\fP
105: .ps -2
106: .sp 1
107: .ce
108: \fIMark Linton\fR
109: .sp 1
110: .ce
111: September 27, 1981
112: .sp 1
113: .br
114: .nr wg 2v
115: .ie \n(.h=\n(vk .nr wg -\n(vhu
116: .el .nr vh 0
117: .if \n(wg>0 \{\
118: .sp \n(wgu
119: .nr vh +\n(wgu \}
120: .nr vk \n(.h
121: .ne 6
122: \fBIntroduction\fP
123: .br
124: .nr wg 1v
125: .ie \n(.h=\n(vk .nr wg -\n(vhu
126: .el .nr vh 0
127: .if \n(wg>0 \{\
128: .sp \n(wgu
129: .nr vh +\n(wgu \}
130: .nr vk \n(.h
131: .ti +5n
132: \fIPdx\fP is a tool for debugging Pascal programs
133: that are translated by the Berkeley Pascal translator \fIpi\fP
134: [Joy, Graham, and Haley 80].
135: This tutorial introduces \fIpdx\fP and the basic ways that it can be used.
136: For a complete reference, consult the \fIpdx\fP manual page.
137: .br
138: .nr wg 2v
139: .ie \n(.h=\n(vk .nr wg -\n(vhu
140: .el .nr vh 0
141: .if \n(wg>0 \{\
142: .sp \n(wgu
143: .nr vh +\n(wgu \}
144: .nr vk \n(.h
145: .ne 6
146: \fBGetting Started\fP
147: .br
148: .nr wg 1v
149: .ie \n(.h=\n(vk .nr wg -\n(vhu
150: .el .nr vh 0
151: .if \n(wg>0 \{\
152: .sp \n(wgu
153: .nr vh +\n(wgu \}
154: .nr vk \n(.h
155: .ti +5n
156: Suppose the program we are working on is in a file called ``prog.p''.
157: Before using \fIpdx\fP, we must translate it with \fIpi\fP.
158: \fIPdx\fP cannot be used if \fIpi\fP reports any errors during translation.
159: To enter \fIpdx\fP, we type the following: (in examples,
160: the user types is in boldface, what \fIpdx\fP prints
161: is in normal type).
162: .br
163: .nr wg 1v
164: .ie \n(.h=\n(vk .nr wg -\n(vhu
165: .el .nr vh 0
166: .if \n(wg>0 \{\
167: .sp \n(wgu
168: .nr vh +\n(wgu \}
169: .nr vk \n(.h
170: .in +8n
171: .nf
172: .ne 5
173: % \fBpdx\fP
174: >
175: .br
176: .nr wg 1v
177: .ie \n(.h=\n(vk .nr wg -\n(vhu
178: .el .nr vh 0
179: .if \n(wg>0 \{\
180: .sp \n(wgu
181: .nr vh +\n(wgu \}
182: .nr vk \n(.h
183: .in -8n
184: .fi
185: The ``>'' is a prompt from \fIpdx\fP.
186: Like the shell or editor, \fIpdx\fP prints the prompt when it
187: is waiting for a command.
188: .br
189: .nr wg 2v
190: .ie \n(.h=\n(vk .nr wg -\n(vhu
191: .el .nr vh 0
192: .if \n(wg>0 \{\
193: .sp \n(wgu
194: .nr vh +\n(wgu \}
195: .nr vk \n(.h
196: .ne 6
197: \fBRunning the Program\fP
198: .br
199: .nr wg 1v
200: .ie \n(.h=\n(vk .nr wg -\n(vhu
201: .el .nr vh 0
202: .if \n(wg>0 \{\
203: .sp \n(wgu
204: .nr vh +\n(wgu \}
205: .nr vk \n(.h
206: .ti +5n
207: Once in \fIpdx\fP, we can begin executing our program
208: by typing the command ``run''.
209: Programs don't usually work the first time;
210: with one of two things happening:
211: .if n .nr In 5
212: .if t .nr In 8
213: .in +\n(Inn
214: .br
215: .nr wg 1v
216: .ie \n(.h=\n(vk .nr wg -\n(vhu
217: .el .nr vh 0
218: .if \n(wg>0 \{\
219: .sp \n(wgu
220: .nr vh +\n(wgu \}
221: .nr vk \n(.h
222: .ti -5n
223: \h'1n'1.\h'2n'\c
224: The program tries to do something that isn't
225: allowed in Pascal, such as dividing by 0.
226: .br
227: .nr wg 1v
228: .ie \n(.h=\n(vk .nr wg -\n(vhu
229: .el .nr vh 0
230: .if \n(wg>0 \{\
231: .sp \n(wgu
232: .nr vh +\n(wgu \}
233: .nr vk \n(.h
234: .ti -5n
235: \h'1n'2.\h'2n'\c
236: The program runs but produces incorrect results.
237: .in -\n(Inn
238: .br
239: .nr wg 1v
240: .ie \n(.h=\n(vk .nr wg -\n(vhu
241: .el .nr vh 0
242: .if \n(wg>0 \{\
243: .sp \n(wgu
244: .nr vh +\n(wgu \}
245: .nr vk \n(.h
246: Let's consider the first case.
247: Suppose ``prog.p'' contains the declarations
248: .br
249: .nr wg 1v
250: .ie \n(.h=\n(vk .nr wg -\n(vhu
251: .el .nr vh 0
252: .if \n(wg>0 \{\
253: .sp \n(wgu
254: .nr vh +\n(wgu \}
255: .nr vk \n(.h
256: .in +8n
257: .nf
258: .ne 5
259: var
260: sum, count : integer;
261: avg : real;
262: .br
263: .nr wg 1v
264: .ie \n(.h=\n(vk .nr wg -\n(vhu
265: .el .nr vh 0
266: .if \n(wg>0 \{\
267: .sp \n(wgu
268: .nr vh +\n(wgu \}
269: .nr vk \n(.h
270: .in -8n
271: .fi
272: and the statement
273: .br
274: .nr wg 1v
275: .ie \n(.h=\n(vk .nr wg -\n(vhu
276: .el .nr vh 0
277: .if \n(wg>0 \{\
278: .sp \n(wgu
279: .nr vh +\n(wgu \}
280: .nr vk \n(.h
281: .in +8n
282: .nf
283: .ne 5
284: avg := sum / count;
285: .br
286: .nr wg 1v
287: .ie \n(.h=\n(vk .nr wg -\n(vhu
288: .el .nr vh 0
289: .if \n(wg>0 \{\
290: .sp \n(wgu
291: .nr vh +\n(wgu \}
292: .nr vk \n(.h
293: .in -8n
294: .fi
295: at line 15.
296: Suppose further that when the program is run
297: ``count'' has the value 0.
298: Running under \fIpdx\fP, the following would be printed:
299: .br
300: .nr wg 1v
301: .ie \n(.h=\n(vk .nr wg -\n(vhu
302: .el .nr vh 0
303: .if \n(wg>0 \{\
304: .sp \n(wgu
305: .nr vh +\n(wgu \}
306: .nr vk \n(.h
307: .in +8n
308: .nf
309: .ne 5
310: > \fBrun\fP
311: .sp 1
312: error at line 15: real divide by zero
313: 15 avg := sum / count;
314: >
315: .br
316: .nr wg 1v
317: .ie \n(.h=\n(vk .nr wg -\n(vhu
318: .el .nr vh 0
319: .if \n(wg>0 \{\
320: .sp \n(wgu
321: .nr vh +\n(wgu \}
322: .nr vk \n(.h
323: .in -8n
324: .fi
325: .br
326: .nr wg 2v
327: .ie \n(.h=\n(vk .nr wg -\n(vhu
328: .el .nr vh 0
329: .if \n(wg>0 \{\
330: .sp \n(wgu
331: .nr vh +\n(wgu \}
332: .nr vk \n(.h
333: .ne 6
334: \fBPrinting Out Variables\fP
335: .br
336: .nr wg 1v
337: .ie \n(.h=\n(vk .nr wg -\n(vhu
338: .el .nr vh 0
339: .if \n(wg>0 \{\
340: .sp \n(wgu
341: .nr vh +\n(wgu \}
342: .nr vk \n(.h
343: .ti +5n
344: When a program stops because of an execution error,
345: \fIpdx\fP prints the error and the line in the program where
346: the error occurred.
347: We can then examine the program's ``state'', that is,
348: print out the values of any variables that might be
349: of interest.
350: In the above example, we might want to know the value
351: of \fIsum\fP, so we say
352: .br
353: .nr wg 1v
354: .ie \n(.h=\n(vk .nr wg -\n(vhu
355: .el .nr vh 0
356: .if \n(wg>0 \{\
357: .sp \n(wgu
358: .nr vh +\n(wgu \}
359: .nr vk \n(.h
360: .in +8n
361: .nf
362: .ne 5
363: > \fBprint sum\fP
364: 5
365: >
366: .br
367: .nr wg 1v
368: .ie \n(.h=\n(vk .nr wg -\n(vhu
369: .el .nr vh 0
370: .if \n(wg>0 \{\
371: .sp \n(wgu
372: .nr vh +\n(wgu \}
373: .nr vk \n(.h
374: .in -8n
375: .fi
376: The print command can be given any number of Pascal expressions
377: separated by commas.
378: .br
379: .nr wg 1v
380: .ie \n(.h=\n(vk .nr wg -\n(vhu
381: .el .nr vh 0
382: .if \n(wg>0 \{\
383: .sp \n(wgu
384: .nr vh +\n(wgu \}
385: .nr vk \n(.h
386: .ne 3
387: .ti +5n
388: We can print the values of all variables by using
389: the ``dump'' command.
390: Continuing our example, we might get
391: .br
392: .nr wg 1v
393: .ie \n(.h=\n(vk .nr wg -\n(vhu
394: .el .nr vh 0
395: .if \n(wg>0 \{\
396: .sp \n(wgu
397: .nr vh +\n(wgu \}
398: .nr vk \n(.h
399: .in +8n
400: .nf
401: .ne 5
402: > \fBdump\fP
403: sum = 5
404: count = 0
405: avg = 0.0
406: >
407: .br
408: .nr wg 1v
409: .ie \n(.h=\n(vk .nr wg -\n(vhu
410: .el .nr vh 0
411: .if \n(wg>0 \{\
412: .sp \n(wgu
413: .nr vh +\n(wgu \}
414: .nr vk \n(.h
415: .in -8n
416: .fi
417: Frequently there are many variables active
418: so that we want to print the list of a file for perusal.
419: This is done by saying
420: .br
421: .nr wg 1v
422: .ie \n(.h=\n(vk .nr wg -\n(vhu
423: .el .nr vh 0
424: .if \n(wg>0 \{\
425: .sp \n(wgu
426: .nr vh +\n(wgu \}
427: .nr vk \n(.h
428: .in +8n
429: .nf
430: .ne 5
431: > \fBdump > out\fP
432: .br
433: .nr wg 1v
434: .ie \n(.h=\n(vk .nr wg -\n(vhu
435: .el .nr vh 0
436: .if \n(wg>0 \{\
437: .sp \n(wgu
438: .nr vh +\n(wgu \}
439: .nr vk \n(.h
440: .in -8n
441: .fi
442: where ``out'' is the name of file which does not exist.
443: .br
444: .nr wg 1v
445: .ie \n(.h=\n(vk .nr wg -\n(vhu
446: .el .nr vh 0
447: .if \n(wg>0 \{\
448: .sp \n(wgu
449: .nr vh +\n(wgu \}
450: .nr vk \n(.h
451: .ne 3
452: .ti +5n
453: There are two other commands useful for printing information
454: about variables.
455: The command ``whatis'' prints out the declaration of a variable.
456: Using the above example,
457: .br
458: .nr wg 1v
459: .ie \n(.h=\n(vk .nr wg -\n(vhu
460: .el .nr vh 0
461: .if \n(wg>0 \{\
462: .sp \n(wgu
463: .nr vh +\n(wgu \}
464: .nr vk \n(.h
465: .in +8n
466: .nf
467: .ne 5
468: > \fBwhatis\fP sum
469: var sum : integer;
470: .br
471: .nr wg 1v
472: .ie \n(.h=\n(vk .nr wg -\n(vhu
473: .el .nr vh 0
474: .if \n(wg>0 \{\
475: .sp \n(wgu
476: .nr vh +\n(wgu \}
477: .nr vk \n(.h
478: .in -8n
479: .fi
480: .br
481: .nr wg 1v
482: .ie \n(.h=\n(vk .nr wg -\n(vhu
483: .el .nr vh 0
484: .if \n(wg>0 \{\
485: .sp \n(wgu
486: .nr vh +\n(wgu \}
487: .nr vk \n(.h
488: .ne 3
489: .ti +5n
490: It is possible for a program to have the same name given
491: to two or more different variables when they are local to
492: different procedures.
493: \fIPi\fP distinguishes the variables according to which procedure
494: it is looking at;
495: however, when debugging it is possible that both procedures
496: are active (for example, one procedure could call the other).
497: .br
498: .nr wg 1v
499: .ie \n(.h=\n(vk .nr wg -\n(vhu
500: .el .nr vh 0
501: .if \n(wg>0 \{\
502: .sp \n(wgu
503: .nr vh +\n(wgu \}
504: .nr vk \n(.h
505: .ne 3
506: .ti +5n
507: \fIPdx\fP normally allows printing of any variable declared within
508: the most recently called procedure or any variables accessible
509: to this procedure.
510: A variable in an active procedure that is not normally accessible
511: can be printed by preceding its name with the procedure it is in
512: and a ``.''.
513: It can sometimes become difficult to remember the variable
514: that a given name is currently associated with.
515: The ``which'' command is useful in resolving this confusion.
516: It prints the variable name along with the procedure that it is contained in.
517: .br
518: .nr wg 1v
519: .ie \n(.h=\n(vk .nr wg -\n(vhu
520: .el .nr vh 0
521: .if \n(wg>0 \{\
522: .sp \n(wgu
523: .nr vh +\n(wgu \}
524: .nr vk \n(.h
525: .ne 3
526: .ti +5n
527: Usually we want to know not only what the values of variables
528: are, but how the program got to where it is.
529: The ``where'' command lists the procedures that were called
530: for the program to reach its current point.
531: It might print, for example,
532: .br
533: .nr wg 1v
534: .ie \n(.h=\n(vk .nr wg -\n(vhu
535: .el .nr vh 0
536: .if \n(wg>0 \{\
537: .sp \n(wgu
538: .nr vh +\n(wgu \}
539: .nr vk \n(.h
540: .in +8n
541: .nf
542: .ne 5
543: > \fBwhere\fP
544: LastCalled(parameters), line 15
545: OneBeforeThat(parameters), line 30
546: MainProgram, line 45
547: >
548: .br
549: .nr wg 1v
550: .ie \n(.h=\n(vk .nr wg -\n(vhu
551: .el .nr vh 0
552: .if \n(wg>0 \{\
553: .sp \n(wgu
554: .nr vh +\n(wgu \}
555: .nr vk \n(.h
556: .in -8n
557: .fi
558: .br
559: .nr wg 2v
560: .ie \n(.h=\n(vk .nr wg -\n(vhu
561: .el .nr vh 0
562: .if \n(wg>0 \{\
563: .sp \n(wgu
564: .nr vh +\n(wgu \}
565: .nr vk \n(.h
566: .ne 6
567: \fBExecution Tracing\fP
568: .br
569: .nr wg 1v
570: .ie \n(.h=\n(vk .nr wg -\n(vhu
571: .el .nr vh 0
572: .if \n(wg>0 \{\
573: .sp \n(wgu
574: .nr vh +\n(wgu \}
575: .nr vk \n(.h
576: .ti +5n
577: Now let's look at the possibility that our program doesn't
578: get an execution error but doesn't produce the correct results.
579: To figure out what and where something is going wrong, we
580: wish to ``watch'' execution information more closely.
581: The \fBtrace\fP command in \fIpdx\fP allows us to do this.
582: There are five classes of information that
583: we can watch:
584: .if n .nr In 5
585: .if t .nr In 8
586: .in +\n(Inn
587: .br
588: .nr wg 1v
589: .ie \n(.h=\n(vk .nr wg -\n(vhu
590: .el .nr vh 0
591: .if \n(wg>0 \{\
592: .sp \n(wgu
593: .nr vh +\n(wgu \}
594: .nr vk \n(.h
595: .ti -3n
596: -\h'2n'\c
597: The execution of a particular source line.
598: .br
599: .nr wg 1v
600: .ie \n(.h=\n(vk .nr wg -\n(vhu
601: .el .nr vh 0
602: .if \n(wg>0 \{\
603: .sp \n(wgu
604: .nr vh +\n(wgu \}
605: .nr vk \n(.h
606: .ti -3n
607: -\h'2n'\c
608: A call to a particular procedure or function.
609: .br
610: .nr wg 1v
611: .ie \n(.h=\n(vk .nr wg -\n(vhu
612: .el .nr vh 0
613: .if \n(wg>0 \{\
614: .sp \n(wgu
615: .nr vh +\n(wgu \}
616: .nr vk \n(.h
617: .ti -3n
618: -\h'2n'\c
619: The value of an expression at a particular source line.
620: .br
621: .nr wg 1v
622: .ie \n(.h=\n(vk .nr wg -\n(vhu
623: .el .nr vh 0
624: .if \n(wg>0 \{\
625: .sp \n(wgu
626: .nr vh +\n(wgu \}
627: .nr vk \n(.h
628: .ti -3n
629: -\h'2n'\c
630: The value of a variable whenever it changes; and the
631: line at which it changes.
632: .br
633: .nr wg 1v
634: .ie \n(.h=\n(vk .nr wg -\n(vhu
635: .el .nr vh 0
636: .if \n(wg>0 \{\
637: .sp \n(wgu
638: .nr vh +\n(wgu \}
639: .nr vk \n(.h
640: .ti -3n
641: -\h'2n'\c
642: The execution of all source lines.
643: .in -\n(Inn
644: .br
645: .nr wg 1v
646: .ie \n(.h=\n(vk .nr wg -\n(vhu
647: .el .nr vh 0
648: .if \n(wg>0 \{\
649: .sp \n(wgu
650: .nr vh +\n(wgu \}
651: .nr vk \n(.h
652: It should be noted that the last two kinds of information
653: are expensive to obtain and will cause your program to run
654: much more slowly than normal.
655: They should be used sparingly.
656: .br
657: .nr wg 1v
658: .ie \n(.h=\n(vk .nr wg -\n(vhu
659: .el .nr vh 0
660: .if \n(wg>0 \{\
661: .sp \n(wgu
662: .nr vh +\n(wgu \}
663: .nr vk \n(.h
664: .ne 3
665: .ti +5n
666: These forms of tracing can be combined and there is no
667: limit to the number of things you can trace at any given time.
668: .br
669: .nr wg 1v
670: .ie \n(.h=\n(vk .nr wg -\n(vhu
671: .el .nr vh 0
672: .if \n(wg>0 \{\
673: .sp \n(wgu
674: .nr vh +\n(wgu \}
675: .nr vk \n(.h
676: .ne 3
677: .ti +5n
678: To trace the execution of a particular source line,
679: type
680: .br
681: .nr wg 1v
682: .ie \n(.h=\n(vk .nr wg -\n(vhu
683: .el .nr vh 0
684: .if \n(wg>0 \{\
685: .sp \n(wgu
686: .nr vh +\n(wgu \}
687: .nr vk \n(.h
688: .in +8n
689: .nf
690: .ne 5
691: > \fBtrace\fP \fIline-number\fP
692: .br
693: .nr wg 1v
694: .ie \n(.h=\n(vk .nr wg -\n(vhu
695: .el .nr vh 0
696: .if \n(wg>0 \{\
697: .sp \n(wgu
698: .nr vh +\n(wgu \}
699: .nr vk \n(.h
700: .in -8n
701: .fi
702: The next time the \fBrun\fP command is given
703: \fIpdx\fP will execute the program, printing the specified line
704: each time it is about to be executed.
705: .br
706: .nr wg 1v
707: .ie \n(.h=\n(vk .nr wg -\n(vhu
708: .el .nr vh 0
709: .if \n(wg>0 \{\
710: .sp \n(wgu
711: .nr vh +\n(wgu \}
712: .nr vk \n(.h
713: .ne 3
714: .ti +5n
715: To trace every call to a procedure,
716: type
717: .br
718: .nr wg 1v
719: .ie \n(.h=\n(vk .nr wg -\n(vhu
720: .el .nr vh 0
721: .if \n(wg>0 \{\
722: .sp \n(wgu
723: .nr vh +\n(wgu \}
724: .nr vk \n(.h
725: .in +8n
726: .nf
727: .ne 5
728: > \fBtrace\fP \fIprocedure-name\fP
729: .br
730: .nr wg 1v
731: .ie \n(.h=\n(vk .nr wg -\n(vhu
732: .el .nr vh 0
733: .if \n(wg>0 \{\
734: .sp \n(wgu
735: .nr vh +\n(wgu \}
736: .nr vk \n(.h
737: .in -8n
738: .fi
739: For each call to the named procedure during execution,
740: \fIpdx\fP will print the name of the procedure, the procedure
741: and line it was called from, and what parameters (if any) it was called with.
742: .br
743: .nr wg 1v
744: .ie \n(.h=\n(vk .nr wg -\n(vhu
745: .el .nr vh 0
746: .if \n(wg>0 \{\
747: .sp \n(wgu
748: .nr vh +\n(wgu \}
749: .nr vk \n(.h
750: .ne 3
751: .ti +5n
752: To see the value of an expression at a particular line,
753: type
754: .br
755: .nr wg 1v
756: .ie \n(.h=\n(vk .nr wg -\n(vhu
757: .el .nr vh 0
758: .if \n(wg>0 \{\
759: .sp \n(wgu
760: .nr vh +\n(wgu \}
761: .nr vk \n(.h
762: .in +8n
763: .nf
764: .ne 5
765: > \fBtrace\fP \fIexpression\fP \fBat\fP \fIsource-line-number\fP
766: .br
767: .nr wg 1v
768: .ie \n(.h=\n(vk .nr wg -\n(vhu
769: .el .nr vh 0
770: .if \n(wg>0 \{\
771: .sp \n(wgu
772: .nr vh +\n(wgu \}
773: .nr vk \n(.h
774: .in -8n
775: .fi
776: To see whenever the value of a variable is changed,
777: we type
778: .br
779: .nr wg 1v
780: .ie \n(.h=\n(vk .nr wg -\n(vhu
781: .el .nr vh 0
782: .if \n(wg>0 \{\
783: .sp \n(wgu
784: .nr vh +\n(wgu \}
785: .nr vk \n(.h
786: .in +8n
787: .nf
788: .ne 5
789: > \fBtrace\fP \fIvariable\fP
790: .br
791: .nr wg 1v
792: .ie \n(.h=\n(vk .nr wg -\n(vhu
793: .el .nr vh 0
794: .if \n(wg>0 \{\
795: .sp \n(wgu
796: .nr vh +\n(wgu \}
797: .nr vk \n(.h
798: .in -8n
799: .fi
800: .br
801: .nr wg 1v
802: .ie \n(.h=\n(vk .nr wg -\n(vhu
803: .el .nr vh 0
804: .if \n(wg>0 \{\
805: .sp \n(wgu
806: .nr vh +\n(wgu \}
807: .nr vk \n(.h
808: .ne 3
809: .ti +5n
810: Finally, to have each source line printed
811: as it's about to be executed, we simply say
812: .br
813: .nr wg 1v
814: .ie \n(.h=\n(vk .nr wg -\n(vhu
815: .el .nr vh 0
816: .if \n(wg>0 \{\
817: .sp \n(wgu
818: .nr vh +\n(wgu \}
819: .nr vk \n(.h
820: .in +8n
821: .nf
822: .ne 5
823: \fBtrace\fP
824: .br
825: .nr wg 1v
826: .ie \n(.h=\n(vk .nr wg -\n(vhu
827: .el .nr vh 0
828: .if \n(wg>0 \{\
829: .sp \n(wgu
830: .nr vh +\n(wgu \}
831: .nr vk \n(.h
832: .in -8n
833: .fi
834: After issuing a trace command, \fIpdx\fP
835: displays all currently active traces.
836: Each command is identified with a number in parentheses.
837: To turn off a trace,
838: give the command
839: .br
840: .nr wg 1v
841: .ie \n(.h=\n(vk .nr wg -\n(vhu
842: .el .nr vh 0
843: .if \n(wg>0 \{\
844: .sp \n(wgu
845: .nr vh +\n(wgu \}
846: .nr vk \n(.h
847: .in +8n
848: .nf
849: .ne 5
850: > \fBdelete\fP \fIcommand-number\fP
851: .br
852: .nr wg 1v
853: .ie \n(.h=\n(vk .nr wg -\n(vhu
854: .el .nr vh 0
855: .if \n(wg>0 \{\
856: .sp \n(wgu
857: .nr vh +\n(wgu \}
858: .nr vk \n(.h
859: .in -8n
860: .fi
861: Tracing information will be printed every time the program is run until
862: it is explicitly turned off by giving the \fBdelete\fP command.
863: .br
864: .nr wg 1v
865: .ie \n(.h=\n(vk .nr wg -\n(vhu
866: .el .nr vh 0
867: .if \n(wg>0 \{\
868: .sp \n(wgu
869: .nr vh +\n(wgu \}
870: .nr vk \n(.h
871: .ne 3
872: .ti +5n
873: To display the information that you are currently tracing, say
874: .br
875: .nr wg 1v
876: .ie \n(.h=\n(vk .nr wg -\n(vhu
877: .el .nr vh 0
878: .if \n(wg>0 \{\
879: .sp \n(wgu
880: .nr vh +\n(wgu \}
881: .nr vk \n(.h
882: .in +8n
883: .nf
884: .ne 5
885: > \fBstatus\fP
886: .br
887: .nr wg 1v
888: .ie \n(.h=\n(vk .nr wg -\n(vhu
889: .el .nr vh 0
890: .if \n(wg>0 \{\
891: .sp \n(wgu
892: .nr vh +\n(wgu \}
893: .nr vk \n(.h
894: .in -8n
895: .fi
896: .br
897: .nr wg 2v
898: .ie \n(.h=\n(vk .nr wg -\n(vhu
899: .el .nr vh 0
900: .if \n(wg>0 \{\
901: .sp \n(wgu
902: .nr vh +\n(wgu \}
903: .nr vk \n(.h
904: .ne 6
905: \fBStopping and Continuing\fP
906: .br
907: .nr wg 1v
908: .ie \n(.h=\n(vk .nr wg -\n(vhu
909: .el .nr vh 0
910: .if \n(wg>0 \{\
911: .sp \n(wgu
912: .nr vh +\n(wgu \}
913: .nr vk \n(.h
914: .ti +5n
915: Sometimes, when debugging, we want to stop our program,
916: look at some data, and then continue execution.
917: The \fBstop\fP command allows the suspension of execution.
918: To continue execution from where it was suspended,
919: the \fBcont\fP command is used.
920: There are four ways to describe when execution should be stopped:
921: .in +5n
922: .if n .nr In 5
923: .if t .nr In 8
924: .in +\n(Inn
925: .ta \n(Inn
926: .br
927: .nr wg 1v
928: .ie \n(.h=\n(vk .nr wg -\n(vhu
929: .el .nr vh 0
930: .if \n(wg>0 \{\
931: .sp \n(wgu
932: .nr vh +\n(wgu \}
933: .nr vk \n(.h
934: .ti -\n(Inn
935: \&\fBstop\fP \fBif\fP \fIcondition\fP
936: .br
937: \c
938: Execution is stopped if the specified condition becomes true.
939: The condition can be any Pascal boolean expression.
940: .br
941: .nr wg 1v
942: .ie \n(.h=\n(vk .nr wg -\n(vhu
943: .el .nr vh 0
944: .if \n(wg>0 \{\
945: .sp \n(wgu
946: .nr vh +\n(wgu \}
947: .nr vk \n(.h
948: .ti -\n(Inn
949: \&\fBstop\fP \fBat\fP \fIsource-line-number\fP
950: .br
951: \c
952: Execution is stopped when the \fIline\fP is about to executed.
953: .br
954: .nr wg 1v
955: .ie \n(.h=\n(vk .nr wg -\n(vhu
956: .el .nr vh 0
957: .if \n(wg>0 \{\
958: .sp \n(wgu
959: .nr vh +\n(wgu \}
960: .nr vk \n(.h
961: .ti -\n(Inn
962: \&\fBstop\fP \fBin\fP \fIprocedure\fP
963: .br
964: \c
965: Execution is stopped when the \fIprocedure\fP is called.
966: .br
967: .nr wg 1v
968: .ie \n(.h=\n(vk .nr wg -\n(vhu
969: .el .nr vh 0
970: .if \n(wg>0 \{\
971: .sp \n(wgu
972: .nr vh +\n(wgu \}
973: .nr vk \n(.h
974: .ti -\n(Inn
975: \&\fBstop\fP \fIvariable\fP
976: .br
977: \c
978: Execution is stopped when the \fIvariable\fP is about to be changed.
979: .in -\n(Inn
980: .br
981: .nr wg 1v
982: .ie \n(.h=\n(vk .nr wg -\n(vhu
983: .el .nr vh 0
984: .if \n(wg>0 \{\
985: .sp \n(wgu
986: .nr vh +\n(wgu \}
987: .nr vk \n(.h
988: .in -5n
989: Execution is also stopped by an interrupt, i.e.
990: by typing the RUB or DEL key.
991: .br
992: .nr wg 1v
993: .ie \n(.h=\n(vk .nr wg -\n(vhu
994: .el .nr vh 0
995: .if \n(wg>0 \{\
996: .sp \n(wgu
997: .nr vh +\n(wgu \}
998: .nr vk \n(.h
999: .ne 3
1000: .ti +5n
1001: Execution can be momentarily continued by the commands \fBnext\fP
1002: and \fBstep\fP.
1003: The \fBnext\fP command stops after one source line has been executed.
1004: The \fBstep\fP command stops at the next source line to be executed.
1005: These are only different when the current source line
1006: contains a call to a procedure or function.
1007: \fBStep\fP will stop at the beginning of the subprogram, \fBnext\fP will not.
1008: As in tracing, stops are set until explicitly unset
1009: with the \fBdelete\fP command.
1010: .br
1011: .nr wg 2v
1012: .ie \n(.h=\n(vk .nr wg -\n(vhu
1013: .el .nr vh 0
1014: .if \n(wg>0 \{\
1015: .sp \n(wgu
1016: .nr vh +\n(wgu \}
1017: .nr vk \n(.h
1018: .ne 6
1019: \fBSource Program Manipulation\fP
1020: .br
1021: .nr wg 1v
1022: .ie \n(.h=\n(vk .nr wg -\n(vhu
1023: .el .nr vh 0
1024: .if \n(wg>0 \{\
1025: .sp \n(wgu
1026: .nr vh +\n(wgu \}
1027: .nr vk \n(.h
1028: .ti +5n
1029: \fIPdx\fP allows you to view your program during debugging.
1030: For example, to print lines 10 to 20 from ``prog.p'', you would type
1031: .br
1032: .nr wg 1v
1033: .ie \n(.h=\n(vk .nr wg -\n(vhu
1034: .el .nr vh 0
1035: .if \n(wg>0 \{\
1036: .sp \n(wgu
1037: .nr vh +\n(wgu \}
1038: .nr vk \n(.h
1039: .in +8n
1040: .nf
1041: .ne 5
1042: > \fBlist\fP 10,20
1043: .br
1044: .nr wg 1v
1045: .ie \n(.h=\n(vk .nr wg -\n(vhu
1046: .el .nr vh 0
1047: .if \n(wg>0 \{\
1048: .sp \n(wgu
1049: .nr vh +\n(wgu \}
1050: .nr vk \n(.h
1051: .in -8n
1052: .fi
1053: If you actually wish to change your program, or look at it
1054: in a more sophisticated manner, the command
1055: .br
1056: .nr wg 1v
1057: .ie \n(.h=\n(vk .nr wg -\n(vhu
1058: .el .nr vh 0
1059: .if \n(wg>0 \{\
1060: .sp \n(wgu
1061: .nr vh +\n(wgu \}
1062: .nr vk \n(.h
1063: .in +8n
1064: .nf
1065: .ne 5
1066: > \fBedit\fP
1067: .br
1068: .nr wg 1v
1069: .ie \n(.h=\n(vk .nr wg -\n(vhu
1070: .el .nr vh 0
1071: .if \n(wg>0 \{\
1072: .sp \n(wgu
1073: .nr vh +\n(wgu \}
1074: .nr vk \n(.h
1075: .in -8n
1076: .fi
1077: will invoke the editor on your program.
1078: You can also say
1079: .br
1080: .nr wg 1v
1081: .ie \n(.h=\n(vk .nr wg -\n(vhu
1082: .el .nr vh 0
1083: .if \n(wg>0 \{\
1084: .sp \n(wgu
1085: .nr vh +\n(wgu \}
1086: .nr vk \n(.h
1087: .in +8n
1088: .nf
1089: .ne 5
1090: > \fBedit\fP \fIprocedure\fP
1091: .br
1092: .nr wg 1v
1093: .ie \n(.h=\n(vk .nr wg -\n(vhu
1094: .el .nr vh 0
1095: .if \n(wg>0 \{\
1096: .sp \n(wgu
1097: .nr vh +\n(wgu \}
1098: .nr vk \n(.h
1099: .in -8n
1100: .fi
1101: and \fIpdx\fP will invoke the editor on your program
1102: and position the current line on the first line of
1103: the \fIprocedure\fP.
1104: .br
1105: .nr wg 1v
1106: .ie \n(.h=\n(vk .nr wg -\n(vhu
1107: .el .nr vh 0
1108: .if \n(wg>0 \{\
1109: .sp \n(wgu
1110: .nr vh +\n(wgu \}
1111: .nr vk \n(.h
1112: .ne 3
1113: .ti +5n
1114: If you change your program and wish to start debugging the
1115: new version, you should give the command
1116: .br
1117: .nr wg 1v
1118: .ie \n(.h=\n(vk .nr wg -\n(vhu
1119: .el .nr vh 0
1120: .if \n(wg>0 \{\
1121: .sp \n(wgu
1122: .nr vh +\n(wgu \}
1123: .nr vk \n(.h
1124: .in +8n
1125: .nf
1126: .ne 5
1127: > \fBpi\fP
1128: .br
1129: .nr wg 1v
1130: .ie \n(.h=\n(vk .nr wg -\n(vhu
1131: .el .nr vh 0
1132: .if \n(wg>0 \{\
1133: .sp \n(wgu
1134: .nr vh +\n(wgu \}
1135: .nr vk \n(.h
1136: .in -8n
1137: .fi
1138: This command runs \fIpi\fP on your program, and automatically
1139: reads in the new information that \fIpdx\fP needs from the new \fIobj\fP file.
1140: .br
1141: .nr wg 2v
1142: .ie \n(.h=\n(vk .nr wg -\n(vhu
1143: .el .nr vh 0
1144: .if \n(wg>0 \{\
1145: .sp \n(wgu
1146: .nr vh +\n(wgu \}
1147: .nr vk \n(.h
1148: .ne 6
1149: \fBCommand Aliasing\fP
1150: .br
1151: .nr wg 1v
1152: .ie \n(.h=\n(vk .nr wg -\n(vhu
1153: .el .nr vh 0
1154: .if \n(wg>0 \{\
1155: .sp \n(wgu
1156: .nr vh +\n(wgu \}
1157: .nr vk \n(.h
1158: .ti +5n
1159: The \fBalias\fP command is used to create a new name for a command.
1160: This is especially useful for saving typing by defining
1161: abbreviations as aliases.
1162: For example, if you gave the command
1163: .br
1164: .nr wg 1v
1165: .ie \n(.h=\n(vk .nr wg -\n(vhu
1166: .el .nr vh 0
1167: .if \n(wg>0 \{\
1168: .sp \n(wgu
1169: .nr vh +\n(wgu \}
1170: .nr vk \n(.h
1171: .in +8n
1172: .nf
1173: .ne 5
1174: > \fBalias\fP r run
1175: .br
1176: .nr wg 1v
1177: .ie \n(.h=\n(vk .nr wg -\n(vhu
1178: .el .nr vh 0
1179: .if \n(wg>0 \{\
1180: .sp \n(wgu
1181: .nr vh +\n(wgu \}
1182: .nr vk \n(.h
1183: .in -8n
1184: .fi
1185: then you could use ``r'' to run your program.
1186: .br
1187: .nr wg 2v
1188: .ie \n(.h=\n(vk .nr wg -\n(vhu
1189: .el .nr vh 0
1190: .if \n(wg>0 \{\
1191: .sp \n(wgu
1192: .nr vh +\n(wgu \}
1193: .nr vk \n(.h
1194: .ne 6
1195: \fBWhere to go from here\fP
1196: .br
1197: .nr wg 1v
1198: .ie \n(.h=\n(vk .nr wg -\n(vhu
1199: .el .nr vh 0
1200: .if \n(wg>0 \{\
1201: .sp \n(wgu
1202: .nr vh +\n(wgu \}
1203: .nr vk \n(.h
1204: .ti +5n
1205: If you feel comfortable what we've discussed here,
1206: you're ready to read the \fIpdx\fP manual page.
1207: It contains a complete, but brief, description of the
1208: commands discussed here along with some other commands that you
1209: might find useful.
1210: .br
1211: .nr wg 2v
1212: .ie \n(.h=\n(vk .nr wg -\n(vhu
1213: .el .nr vh 0
1214: .if \n(wg>0 \{\
1215: .sp \n(wgu
1216: .nr vh +\n(wgu \}
1217: .nr vk \n(.h
1218: .ne 6
1219: \fBReferences\fP
1220: .br
1221: .nr wg 1v
1222: .ie \n(.h=\n(vk .nr wg -\n(vhu
1223: .el .nr vh 0
1224: .if \n(wg>0 \{\
1225: .sp \n(wgu
1226: .nr vh +\n(wgu \}
1227: .nr vk \n(.h
1228: .ti +5n
1229: .ti -5n
1230: .if n .nr In 5
1231: .if t .nr In 8
1232: .in +\n(Inn
1233: .ta \n(Inn
1234: .br
1235: .nr wg 1v
1236: .ie \n(.h=\n(vk .nr wg -\n(vhu
1237: .el .nr vh 0
1238: .if \n(wg>0 \{\
1239: .sp \n(wgu
1240: .nr vh +\n(wgu \}
1241: .nr vk \n(.h
1242: .ti -\n(Inn
1243: \&[Joy, Graham and Haley 80]
1244: .br
1245: \c
1246: Joy, W., Graham, S., and Haley, C.,
1247: ``Berkeley Pascal User's Manual'',
1248: version 2.0, EECS Dept., Univ. of Calif. at Berkeley, October 1980.
1249: .in -\n(Inn
1250: .br
1251: .nr wg 1v
1252: .ie \n(.h=\n(vk .nr wg -\n(vhu
1253: .el .nr vh 0
1254: .if \n(wg>0 \{\
1255: .sp \n(wgu
1256: .nr vh +\n(wgu \}
1257: .nr vk \n(.h
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.