|
|
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.