Commit | Line | Data |
---|---|---|
3edcb7c8 KB |
1 | .\" %sccs.include.proprietary.roff% |
2 | .\" | |
3 | .\" @(#)adb.ms 6.2 (Berkeley) %G% | |
25971d3b KM |
4 | .\" |
5 | .EH 'PS1:10-%''A Tutorial Introduction to ADB' | |
6 | .OH 'A Tutorial Introduction to ADB''PS1:10-%' | |
7 | .de P1 | |
8 | .sp .5 | |
9 | .if \\n(.$>0 .ta \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 | |
10 | .if \\n(.$=0 .ta 1i 1.7i 2.5i | |
11 | .ft 3 | |
12 | .nf | |
13 | .. | |
14 | .de P2 | |
15 | .sp .5 | |
16 | .ft 1 | |
17 | .fi | |
18 | .. | |
19 | .\".RP | |
20 | .....TM "77-8234-11 77-1273-10" "49170-220 39199" "40952-1 39199-11" | |
21 | .ND May 5, 1977 | |
22 | .TL | |
23 | A Tutorial Introduction to ADB | |
24 | .AU "MH2F-207" "3816" | |
25 | J. F. Maranzano | |
26 | .AU "MH2C-512" 7419 | |
27 | S. R. Bourne | |
28 | .AI | |
29 | .MH | |
30 | .OK | |
31 | .\"UNIX | |
32 | .\"Debugging | |
33 | .\"C Programming | |
34 | .AB | |
35 | .PP | |
36 | Debugging tools generally provide a wealth of information | |
37 | about the inner workings of programs. | |
38 | These tools have been available on | |
39 | .UX | |
40 | to allow users to | |
41 | examine ``core'' files | |
42 | that result from aborted programs. | |
43 | A new debugging program, ADB, provides enhanced capabilities | |
44 | to examine "core" and other program files in a | |
45 | variety of formats, run programs with embedded breakpoints and patch files. | |
46 | .PP | |
47 | ADB is an indispensable but complex tool for debugging crashed systems and/or | |
48 | programs. | |
49 | This document provides an introduction to ADB with examples of its use. | |
50 | It explains the various formatting options, | |
51 | techniques for debugging C programs, examples of printing | |
52 | file system information and patching. | |
53 | .AE | |
54 | .CS 12 15 27 13 0 5 | |
55 | .NH | |
56 | Introduction | |
57 | .PP | |
58 | ADB is a new debugging program that is | |
59 | available on UNIX. | |
60 | It provides capabilities to look at | |
61 | ``core'' files resulting from aborted programs, print output in a | |
62 | variety of formats, patch files, and run programs | |
63 | with embedded breakpoints. | |
64 | This document provides examples of | |
65 | the more useful features of ADB. | |
66 | The reader is expected to be | |
67 | familiar with the basic commands on | |
68 | .UX | |
69 | with the C | |
70 | language, and with References 1, 2 and 3. | |
71 | .NH | |
72 | A Quick Survey | |
73 | .NH 2 | |
74 | Invocation | |
75 | .PP | |
76 | ADB is invoked as: | |
77 | .P1 | |
78 | adb objfile corefile | |
79 | .P2 | |
80 | where | |
81 | .ul | |
82 | objfile | |
83 | is an executable UNIX file and | |
84 | .ul | |
85 | corefile | |
86 | is a core image file. | |
87 | Many times this will look like: | |
88 | .P1 | |
89 | adb a.out core | |
90 | .P2 | |
91 | or more simply: | |
92 | .P1 | |
93 | adb | |
94 | .P2 | |
95 | where the defaults are | |
96 | .ul | |
97 | a.out | |
98 | and | |
99 | .ul | |
100 | core | |
101 | respectively. | |
102 | The filename minus (\-) means ignore this argument as in: | |
103 | .P1 | |
104 | adb \- core | |
105 | .P2 | |
106 | .PP | |
107 | ADB has requests for examining locations in either file. | |
108 | The | |
109 | \fB?\fP | |
110 | request examines the contents of | |
111 | .ul | |
112 | objfile, | |
113 | the | |
114 | \fB/\fP | |
115 | request examines the | |
116 | .ul | |
117 | corefile. | |
118 | The general form of these requests is: | |
119 | .P1 | |
120 | address ? format | |
121 | .P2 | |
122 | or | |
123 | .P1 | |
124 | address / format | |
125 | .P2 | |
126 | .NH 2 | |
127 | Current Address | |
128 | .PP | |
129 | ADB maintains a current address, called dot, | |
130 | similar in function to the current pointer in the UNIX editor. | |
131 | When an address is entered, the current address is set to that location, | |
132 | so that: | |
133 | .P1 | |
134 | 0126?i | |
135 | .P2 | |
136 | sets dot to octal 126 and prints the instruction | |
137 | at that address. | |
138 | The request: | |
139 | .P1 | |
140 | .,10/d | |
141 | .P2 | |
142 | prints 10 decimal numbers starting at dot. | |
143 | Dot ends up referring to the address of the last item printed. | |
144 | When used with the \fB?\fP or \fB/\fP requests, | |
145 | the current address can be advanced by typing newline; it can be decremented | |
146 | by typing \fB^\fP. | |
147 | .PP | |
148 | Addresses are represented by | |
149 | expressions. | |
150 | Expressions are made up from decimal, octal, and hexadecimal integers, | |
151 | and symbols from the program under test. | |
152 | These may be combined with the operators +, \-, *, % (integer division), | |
153 | & (bitwise and), | (bitwise inclusive or), # (round up | |
154 | to the next multiple), and ~ (not). | |
155 | (All arithmetic within ADB is 32 bits.) | |
156 | When typing a symbolic address for a C program, | |
157 | the user can type | |
158 | .ul | |
159 | name | |
160 | or | |
161 | .ul | |
162 | _name; | |
163 | ADB will recognize both forms. | |
164 | .NH 2 | |
165 | Formats | |
166 | .PP | |
167 | To print data, a user specifies a collection of letters and characters | |
168 | that describe the format of the printout. | |
169 | Formats are "remembered" in the sense that typing a request without one | |
170 | will cause the new printout to appear in the previous format. | |
171 | The following are the most commonly used format letters. | |
172 | .P1 | |
173 | \fB b \fPone byte in octal | |
174 | \fB c \fPone byte as a character | |
175 | \fB o \fPone word in octal | |
176 | \fB d \fPone word in decimal | |
177 | \fB f \fPtwo words in floating point | |
178 | \fB i \fPPDP 11 instruction | |
179 | \fB s \fPa null terminated character string | |
180 | \fB a \fPthe value of dot | |
181 | \fB u \fPone word as unsigned integer | |
182 | \fB n \fPprint a newline | |
183 | \fB r \fPprint a blank space | |
184 | \fB ^ \fPbackup dot | |
185 | .P2 | |
186 | (Format letters are also available for "long" values, | |
187 | for example, `\fBD\fR' for long decimal, and `\fBF\fP' for double floating point.) | |
188 | For other formats see the ADB manual. | |
189 | .NH 2 | |
190 | General Request Meanings | |
191 | .PP | |
192 | The general form of a request is: | |
193 | .P1 | |
194 | address,count command modifier | |
195 | .P2 | |
196 | which sets `dot' to \fIaddress\fP | |
197 | and executes the command | |
198 | \fIcount\fR times. | |
199 | .PP | |
200 | The following table illustrates some general ADB command meanings: | |
201 | .P1 | |
202 | Command Meaning | |
203 | \fB ? \fPPrint contents from \fIa.out\fP file | |
204 | \fB / \fPPrint contents from \fIcore\fP file | |
205 | \fB = \fPPrint value of "dot" | |
206 | \fB : \fPBreakpoint control | |
207 | \fB $ \fPMiscellaneous requests | |
208 | \fB ; \fPRequest separator | |
209 | \fB ! \fPEscape to shell | |
210 | .P2 | |
211 | .PP | |
212 | ADB catches signals, so a user cannot use a quit signal to exit from ADB. | |
213 | The request $q or $Q (or cntl-D) must be used | |
214 | to exit from ADB. | |
215 | .NH | |
216 | Debugging C Programs | |
217 | .NH 2 | |
218 | Debugging A Core Image | |
219 | .PP | |
220 | Consider the C program in Figure 1. | |
221 | The program is used to illustrate a common error made by | |
222 | C programmers. | |
223 | The object of the program is to change the | |
224 | lower case "t" to upper case in the string pointed to by | |
225 | .ul | |
226 | charp | |
227 | and then write the character string to the file indicated by | |
228 | argument 1. | |
229 | The bug shown is that the character "T" | |
230 | is stored in the pointer | |
231 | .ul | |
232 | charp | |
233 | instead of the string pointed to by | |
234 | .ul | |
235 | charp. | |
236 | Executing the program produces a core file because of an out of bounds memory reference. | |
237 | .PP | |
238 | ADB is invoked by: | |
239 | .P1 | |
240 | adb a.out core | |
241 | .P2 | |
242 | The first debugging request: | |
243 | .P1 | |
244 | $c | |
245 | .P2 | |
246 | is used to give a C backtrace through the | |
247 | subroutines called. | |
248 | As shown in Figure 2 | |
249 | only one function (\fImain\fR) was called and the | |
250 | arguments | |
251 | .ul | |
252 | argc | |
253 | and | |
254 | .ul | |
255 | argv | |
256 | have octal values 02 and | |
257 | 0177762 respectively. | |
258 | Both of these values look | |
259 | reasonable; 02 = two arguments, 0177762 = address on stack | |
260 | of parameter vector. | |
261 | .br | |
262 | The next request: | |
263 | .P1 | |
264 | $C | |
265 | .P2 | |
266 | is used to give a C backtrace plus an interpretation | |
267 | of all the local variables in each function and their | |
268 | values in octal. | |
269 | The value of the variable | |
270 | .ul | |
271 | cc | |
272 | looks incorrect | |
273 | since | |
274 | .ul | |
275 | cc | |
276 | was declared as a character. | |
277 | .PP | |
278 | The next request: | |
279 | .P1 | |
280 | $r | |
281 | .P2 | |
282 | prints out the registers including the program | |
283 | counter and an interpretation of the instruction at that | |
284 | location. | |
285 | .PP | |
286 | The request: | |
287 | .P1 | |
288 | $e | |
289 | .P2 | |
290 | prints out the values of all external variables. | |
291 | .PP | |
292 | A map exists for each file | |
293 | handled by | |
294 | ADB. | |
295 | The map for the | |
296 | .ul | |
297 | a.out | |
298 | file is referenced by \fB?\fP whereas the map for | |
299 | .ul | |
300 | core | |
301 | file is referenced by \fB/\fP. | |
302 | Furthermore, a good rule of thumb is to use \fB?\fP for | |
303 | instructions and \fB/\fP for data when looking at programs. | |
304 | To print out information about the maps type: | |
305 | .P1 | |
306 | $m | |
307 | .P2 | |
308 | This produces a report of the contents of the maps. | |
309 | More about these maps later. | |
310 | .PP | |
311 | In our example, it is useful to see the | |
312 | contents of the string pointed to by | |
313 | .ul | |
314 | charp. | |
315 | This is done by: | |
316 | .P1 | |
317 | *charp/s | |
318 | .P2 | |
319 | which says use | |
320 | .ul | |
321 | charp | |
322 | as a pointer in the | |
323 | .ul | |
324 | core | |
325 | file | |
326 | and print the information as a character string. | |
327 | This printout clearly shows that the character buffer | |
328 | was incorrectly overwritten and helps identify the error. | |
329 | Printing the locations around | |
330 | .ul | |
331 | charp | |
332 | shows that the buffer is unchanged | |
333 | but that the pointer is destroyed. | |
334 | Using ADB similarly, we could print information about the | |
335 | arguments to a function. | |
336 | The request: | |
337 | .P1 | |
338 | main.argc/d | |
339 | .P2 | |
340 | prints the decimal | |
341 | .ul | |
342 | core | |
343 | image value of the argument | |
344 | .ul | |
345 | argc | |
346 | in the function | |
347 | .ul | |
348 | main. | |
349 | .br | |
350 | The request: | |
351 | .P1 | |
352 | *main.argv,3/o | |
353 | .P2 | |
354 | prints the octal values of the three consecutive | |
355 | cells pointed to by | |
356 | .ul | |
357 | argv | |
358 | in the function | |
359 | .ul | |
360 | main. | |
361 | Note that these values are the addresses of the arguments | |
362 | to main. | |
363 | Therefore: | |
364 | .P1 | |
365 | 0177770/s | |
366 | .P2 | |
367 | prints the ASCII value of the first argument. | |
368 | Another way to print this value would have been | |
369 | .P1 | |
370 | *"/s | |
371 | .P2 | |
372 | The " means ditto which remembers the last address | |
373 | typed, in this case \fImain.argc\fP ; the \fB*\fP instructs ADB to use the address field of the | |
374 | .ul | |
375 | core | |
376 | file as a pointer. | |
377 | .PP | |
378 | The request: | |
379 | .P1 | |
380 | .=o | |
381 | .P2 | |
382 | prints the current address (not its contents) in octal which has been set to the address of the first argument. | |
383 | The current address, dot, is used by ADB to | |
384 | "remember" its current location. | |
385 | It allows the user | |
386 | to reference locations relative to the current | |
387 | address, for example: | |
388 | .P1 | |
389 | .\-10/d | |
390 | .P2 | |
391 | .NH 2 | |
392 | Multiple Functions | |
393 | .PP | |
394 | Consider the C program illustrated in | |
395 | Figure 3. | |
396 | This program calls functions | |
397 | .ul | |
398 | f, g, | |
399 | and | |
400 | .ul | |
401 | h | |
402 | until the stack is exhausted and a core image is produced. | |
403 | .PP | |
404 | Again you can enter the debugger via: | |
405 | .P1 | |
406 | adb | |
407 | .P2 | |
408 | which assumes the names | |
409 | .ul | |
410 | a.out | |
411 | and | |
412 | .ul | |
413 | core | |
414 | for the executable | |
415 | file and core image file respectively. | |
416 | The request: | |
417 | .P1 | |
418 | $c | |
419 | .P2 | |
420 | will fill a page of backtrace references to | |
421 | .ul | |
422 | f, g, | |
423 | and | |
424 | .ul | |
425 | h. | |
426 | Figure 4 shows an abbreviated list (typing | |
427 | .ul | |
428 | DEL | |
429 | will terminate the output and bring you back to ADB request level). | |
430 | .PP | |
431 | The request: | |
432 | .P1 | |
433 | ,5$C | |
434 | .P2 | |
435 | prints the five most recent activations. | |
436 | .PP | |
437 | Notice that each function | |
438 | (\fIf,g,h\fP) has a counter | |
439 | of the number of times it was called. | |
440 | .PP | |
441 | The request: | |
442 | .P1 | |
443 | fcnt/d | |
444 | .P2 | |
445 | prints the decimal value of the counter for the function | |
446 | .ul | |
447 | f. | |
448 | Similarly | |
449 | .ul | |
450 | gcnt | |
451 | and | |
452 | .ul | |
453 | hcnt | |
454 | could be printed. | |
455 | To print the value of an automatic variable, | |
456 | for example the decimal value of | |
457 | .ul | |
458 | x | |
459 | in the last call of the function | |
460 | .ul | |
461 | h, | |
462 | type: | |
463 | .P1 | |
464 | h.x/d | |
465 | .P2 | |
466 | It is currently not possible in the exported version to print stack frames other than the most recent activation of a function. | |
467 | Therefore, a user can print everything with | |
468 | \fB$C\fR or the occurrence of a variable in the most recent call of a function. | |
469 | It is possible with the \fB$C\fR request, however, to print the stack frame | |
470 | starting at some address as \fBaddress$C.\fR | |
471 | .NH 2 | |
472 | Setting Breakpoints | |
473 | .PP | |
474 | Consider the C program in Figure 5. | |
475 | This program, which changes tabs into blanks, is adapted from | |
476 | .ul | |
477 | Software Tools | |
478 | by Kernighan and Plauger, pp. 18-27. | |
479 | .PP | |
480 | We will run this program under the control of ADB (see Figure 6a) by: | |
481 | .P1 | |
482 | adb a.out \- | |
483 | .P2 | |
484 | Breakpoints are set in the program as: | |
485 | .ul | |
486 | .P1 | |
487 | address:b [request] | |
488 | .P2 | |
489 | The requests: | |
490 | .P1 | |
491 | settab+4:b | |
492 | fopen+4:b | |
493 | getc+4:b | |
494 | tabpos+4:b | |
495 | .P2 | |
496 | set breakpoints at the start of these functions. | |
497 | C does not generate statement labels. | |
498 | Therefore it is currently not possible to plant breakpoints at locations | |
499 | other than function entry points without a knowledge of the code | |
500 | generated by the C compiler. | |
501 | The above addresses are entered as | |
502 | .ft B | |
503 | symbol+4 | |
504 | .ft R | |
505 | so that they will appear in any | |
506 | C backtrace since the first instruction of each function is a call | |
507 | to the C save routine | |
508 | (\fIcsv\fR). | |
509 | Note that some of the functions are from the C library. | |
510 | .PP | |
511 | To print the location of breakpoints one types: | |
512 | .P1 | |
513 | $b | |
514 | .P2 | |
515 | The display indicates a | |
516 | .ul | |
517 | count | |
518 | field. | |
519 | A breakpoint is bypassed | |
520 | .ul | |
521 | count \-1 | |
522 | times before causing a stop. | |
523 | The | |
524 | .ul | |
525 | command | |
526 | field indicates the ADB requests to be executed each time the breakpoint is encountered. | |
527 | In our example no | |
528 | .ul | |
529 | command | |
530 | fields are present. | |
531 | .PP | |
532 | By displaying the original instructions at the function | |
533 | .ul | |
534 | settab | |
535 | we see that | |
536 | the breakpoint is set after the jsr to the C save routine. | |
537 | We can display the instructions using the ADB request: | |
538 | .P1 | |
539 | settab,5?ia | |
540 | .P2 | |
541 | This request displays five instructions starting at | |
542 | .ul | |
543 | settab | |
544 | with the addresses of each location displayed. | |
545 | Another variation is: | |
546 | .P1 | |
547 | settab,5?i | |
548 | .P2 | |
549 | which displays the instructions with only the starting address. | |
550 | .PP | |
551 | Notice that we accessed the addresses from the | |
552 | .ul | |
553 | a.out | |
554 | file with the \fB?\fP command. | |
555 | In general when asking for a printout of multiple items, | |
556 | ADB will advance the current address the number of | |
557 | bytes necessary to satisfy the request; in the above | |
558 | example five instructions were displayed and the current address was | |
559 | advanced 18 (decimal) bytes. | |
560 | .PP | |
561 | To run the program one simply types: | |
562 | .P1 | |
563 | :r | |
564 | .P2 | |
565 | To delete a breakpoint, for instance the entry to the function | |
566 | .ul | |
567 | settab, | |
568 | one types: | |
569 | .P1 | |
570 | settab+4:d | |
571 | .P2 | |
572 | To continue execution of the program from the breakpoint type: | |
573 | .P1 | |
574 | :c | |
575 | .PP | |
576 | Once the program has stopped (in this case at the breakpoint for | |
577 | .ul | |
578 | fopen), | |
579 | ADB requests can be used to display the contents of memory. | |
580 | For example: | |
581 | .P1 | |
582 | $C | |
583 | .P2 | |
584 | to display a stack trace, or: | |
585 | .P1 | |
586 | tabs,3/8o | |
587 | .P2 | |
588 | to print three lines of 8 locations each from the array called | |
589 | .ul | |
590 | tabs. | |
591 | By this time (at location | |
592 | .ul | |
593 | fopen) | |
594 | in the C program, | |
595 | .ul | |
596 | settab | |
597 | has been called and should have set a one in every eighth location of | |
598 | .ul | |
599 | tabs. | |
600 | .NH 2 | |
601 | Advanced Breakpoint Usage | |
602 | .PP | |
603 | We continue execution of the program with: | |
604 | .P1 | |
605 | :c | |
606 | .P2 | |
607 | See Figure 6b. | |
608 | .ul | |
609 | Getc | |
610 | is called three times and the contents of the variable | |
611 | .ul | |
612 | c | |
613 | in the function | |
614 | .ul | |
615 | main | |
616 | are displayed | |
617 | each time. | |
618 | The single character on the left hand edge is the output from the C program. | |
619 | On the third occurrence of | |
620 | .ul | |
621 | getc | |
622 | the program stops. | |
623 | We can look at the full buffer of characters by typing: | |
624 | .P1 | |
625 | ibuf+6/20c | |
626 | .P2 | |
627 | When we continue the program with: | |
628 | .P1 | |
629 | :c | |
630 | .P2 | |
631 | we hit our first breakpoint at | |
632 | .ul | |
633 | tabpos | |
634 | since there is a tab following the | |
635 | "This" word of the data. | |
636 | .PP | |
637 | Several breakpoints of | |
638 | .ul | |
639 | tabpos | |
640 | will occur until the program has changed the tab into equivalent blanks. | |
641 | Since we feel that | |
642 | .ul | |
643 | tabpos | |
644 | is working, | |
645 | we can remove the breakpoint at that location by: | |
646 | .P1 | |
647 | tabpos+4:d | |
648 | .P2 | |
649 | If the program is continued with: | |
650 | .P1 | |
651 | :c | |
652 | .P2 | |
653 | it resumes normal execution after ADB prints | |
654 | the message | |
655 | .P1 | |
656 | a.out:running | |
657 | .P2 | |
658 | .PP | |
659 | The UNIX quit and interrupt signals | |
660 | act on ADB itself rather than on the program being debugged. | |
661 | If such a signal occurs then the program being debugged is stopped and control is returned to ADB. | |
662 | The signal is saved by ADB and is passed on to the test program if: | |
663 | .P1 | |
664 | :c | |
665 | .P2 | |
666 | is typed. | |
667 | This can be useful when testing interrupt | |
668 | handling routines. | |
669 | The signal is not passed on to the test program if: | |
670 | .P1 | |
671 | :c 0 | |
672 | .P2 | |
673 | is typed. | |
674 | .PP | |
675 | Now let us reset the breakpoint at | |
676 | .ul | |
677 | settab | |
678 | and display the instructions located there when we reach the breakpoint. | |
679 | This is accomplished by: | |
680 | .P1 | |
681 | settab+4:b settab,5?ia \fR* | |
682 | .P2 | |
683 | .FS | |
684 | * Owing to a bug in early versions of ADB (including the | |
685 | version distributed in Generic 3 UNIX) these statements | |
686 | must be written as: | |
687 | .br | |
688 | .in 1i | |
689 | \fBsettab+4:b settab,5?ia;0\fR | |
690 | .ft B | |
691 | .br | |
692 | getc+4,3:b main.c?C;0 | |
693 | .br | |
694 | settab+4:b settab,5?ia; ptab/o;0 | |
695 | .br | |
696 | .ft R | |
697 | .in -1i | |
698 | Note that \fB;0\fR will set dot to zero and stop at the breakpoint. | |
699 | .FE | |
700 | It is also possible to execute the ADB requests for each occurrence of the breakpoint but | |
701 | only stop after the third occurrence by typing: | |
702 | .P1 | |
703 | getc+4,3:b main.c?C \fR* | |
704 | .P2 | |
705 | This request will print the local variable | |
706 | .ul | |
707 | c | |
708 | in the function | |
709 | .ul | |
710 | main | |
711 | at each occurrence of the breakpoint. | |
712 | The semicolon is used to separate multiple ADB requests on a single line. | |
713 | .PP | |
714 | Warning: | |
715 | setting a breakpoint causes the value of dot to be changed; | |
716 | executing the program under ADB does not change dot. | |
717 | Therefore: | |
718 | .P1 | |
719 | settab+4:b .,5?ia | |
720 | fopen+4:b | |
721 | .P2 | |
722 | will print the last thing dot was set to | |
723 | (in the example \fIfopen+4\fP) | |
724 | .ul | |
725 | not | |
726 | the current location (\fIsettab+4\fP) | |
727 | at which the program is executing. | |
728 | .PP | |
729 | A breakpoint can be overwritten without first deleting the old breakpoint. | |
730 | For example: | |
731 | .P1 | |
732 | settab+4:b settab,5?ia; ptab/o \fR* | |
733 | .P2 | |
734 | could be entered after typing the above requests. | |
735 | .PP | |
736 | Now the display of breakpoints: | |
737 | .P1 | |
738 | $b | |
739 | .P2 | |
740 | shows the above request for the | |
741 | .ul | |
742 | settab | |
743 | breakpoint. | |
744 | When the breakpoint at | |
745 | .ul | |
746 | settab | |
747 | is encountered the ADB requests are executed. | |
748 | Note that the location at | |
749 | .ul | |
750 | settab+4 | |
751 | has been changed to plant the breakpoint; | |
752 | all the other locations match their original value. | |
753 | .PP | |
754 | Using the functions, | |
755 | .ul | |
756 | f, g | |
757 | and | |
758 | .ul | |
759 | h | |
760 | shown in Figure 3, | |
761 | we can follow the execution of each function by planting non-stopping | |
762 | breakpoints. | |
763 | We call ADB with the executable program of Figure 3 as follows: | |
764 | .P1 | |
765 | adb ex3 \- | |
766 | .P2 | |
767 | Suppose we enter the following breakpoints: | |
768 | .P1 | |
769 | h+4:b hcnt/d; h.hi/; h.hr/ | |
770 | g+4:b gcnt/d; g.gi/; g.gr/ | |
771 | f+4:b fcnt/d; f.fi/; f.fr/ | |
772 | :r | |
773 | .P2 | |
774 | Each request line indicates that the variables are printed in decimal | |
775 | (by the specification \fBd\fR). | |
776 | Since the format is not changed, the \fBd\fR can be left off all but | |
777 | the first request. | |
778 | .PP | |
779 | The output in Figure 7 illustrates two points. | |
780 | First, the ADB requests in the breakpoint line are not | |
781 | examined until the program under | |
782 | test is run. | |
783 | That means any errors in those ADB requests is not detected until run time. | |
784 | At the location of the error ADB stops running the program. | |
785 | .PP | |
786 | The second point is the way ADB handles register variables. | |
787 | ADB uses the symbol table to address variables. | |
788 | Register variables, like \fIf.fr\fR above, have pointers to uninitialized | |
789 | places on the stack. | |
790 | Therefore the message "symbol not found". | |
791 | .PP | |
792 | Another way of getting at the data in this example is to print | |
793 | the variables used in the call as: | |
794 | .P1 | |
795 | f+4:b fcnt/d; f.a/; f.b/; f.fi/ | |
796 | g+4:b gcnt/d; g.p/; g.q/; g.gi/ | |
797 | :c | |
798 | .P2 | |
799 | The operator / was used instead of ? | |
800 | to read values from the \fIcore\fP file. | |
801 | The output for each function, as shown in Figure 7, has the same format. | |
802 | For the function \fIf\fP, for example, it shows the name and value of the | |
803 | .ul | |
804 | external | |
805 | variable | |
806 | .ul | |
807 | fcnt. | |
808 | It also shows the address on the stack and value of the | |
809 | variables | |
810 | .ul | |
811 | a, b | |
812 | and | |
813 | .ul | |
814 | fi. | |
815 | .PP | |
816 | Notice that the addresses on the stack will continue to decrease | |
817 | until no address space is left for program execution | |
818 | at which time (after many pages of output) | |
819 | the program under test aborts. | |
820 | A display with names would be produced by requests like the following: | |
821 | .P1 | |
822 | f+4:b fcnt/d; f.a/"a="d; f.b/"b="d; f.fi/"fi="d | |
823 | .P2 | |
824 | In this format the quoted string is printed literally and the \fBd\fP | |
825 | produces a decimal display of the variables. | |
826 | The results are shown in Figure 7. | |
827 | .NH 2 | |
828 | Other Breakpoint Facilities | |
829 | .LP | |
830 | .IP \(bu 4 | |
831 | Arguments and change of standard input and output are passed to a program as: | |
832 | .P1 | |
833 | :r arg1 arg2 ... <infile >outfile | |
834 | .P2 | |
835 | This request | |
836 | kills any existing program under test and | |
837 | starts the | |
838 | .ul | |
839 | a.out | |
840 | afresh. | |
841 | .IP \(bu | |
842 | The program being debugged can be single stepped | |
843 | by: | |
844 | .P1 | |
845 | :s | |
846 | .P2 | |
847 | If necessary, this request will start up the program being | |
848 | debugged and stop after executing | |
849 | the first instruction. | |
850 | .IP \(bu | |
851 | ADB allows a program to be entered at a specific address | |
852 | by typing: | |
853 | .P1 | |
854 | address:r | |
855 | .P2 | |
856 | .IP \(bu | |
857 | The count field can be used to skip the first \fIn\fR breakpoints as: | |
858 | .P1 | |
859 | ,n:r | |
860 | .P2 | |
861 | The request: | |
862 | .P1 | |
863 | ,n:c | |
864 | .P2 | |
865 | may also be used for skipping the first \fIn\fR breakpoints | |
866 | when continuing a program. | |
867 | .sp | |
868 | .IP \(bu | |
869 | A program can be continued at an address different from the breakpoint by: | |
870 | .P1 | |
871 | address:c | |
872 | .P2 | |
873 | .IP \(bu | |
874 | The program being debugged runs as a separate process and can be killed by: | |
875 | .P1 | |
876 | :k | |
877 | .P2 | |
878 | .LP | |
879 | .NH | |
880 | Maps | |
881 | .PP | |
882 | UNIX supports several executable file formats. These are used to tell | |
883 | the loader how to load the program file. File type 407 | |
884 | is the most common and is generated by a C compiler invocation such as | |
885 | \fBcc pgm.c\fP. | |
886 | A 410 file is produced by a C compiler command of the form \fBcc -n pgm.c\fP, | |
887 | whereas a 411 file is produced by \fBcc -i pgm.c\fP. | |
888 | ADB interprets these different file formats and | |
889 | provides access to the different segments through a set of maps (see Figure 8). | |
890 | To print the maps type: | |
891 | .P1 | |
892 | $m | |
893 | .P2 | |
894 | .PP | |
895 | In 407 files, both text (instructions) and data are intermixed. | |
896 | This makes it impossible for ADB to differentiate data from | |
897 | instructions and some of the printed symbolic addresses look incorrect; | |
898 | for example, printing data addresses as offsets from routines. | |
899 | .PP | |
900 | In 410 files (shared text), the instructions are separated from data and | |
901 | \fB?*\fR accesses the data part of the \fIa.out\fP file. | |
902 | The \fB?* \fP request tells ADB to use the second part of the | |
903 | map in the | |
904 | .ul | |
905 | a.out | |
906 | file. | |
907 | Accessing data in the \fIcore\fP file shows | |
908 | the data after it was modified by the execution of the program. | |
909 | Notice also that the data segment may have grown during | |
910 | program execution. | |
911 | .PP | |
912 | In 411 files (separated I & D space), the | |
913 | instructions and data are also separated. | |
914 | However, in this | |
915 | case, since data is mapped through a separate set of segmentation | |
916 | registers, the base of the data segment is also relative to address zero. | |
917 | In this case since the addresses overlap it is necessary to use | |
918 | the \fB?*\fR operator to access the data space of the \fIa.out\fP file. | |
919 | In both 410 and 411 files the corresponding | |
920 | core file does not contain the program text. | |
921 | .PP | |
922 | Figure 9 shows the display of three maps | |
923 | for the same program linked as a 407, 410, 411 respectively. | |
924 | The b, e, and f fields are used by ADB to map | |
925 | addresses into file addresses. | |
926 | The "f1" field is the | |
927 | length of the header at the beginning of the file (020 bytes | |
928 | for an \fIa.out\fP file and 02000 bytes for a \fIcore\fP file). | |
929 | The "f2" field is the displacement from the beginning of the file to the data. | |
930 | For a 407 file with mixed text and data this is the | |
931 | same as the length of the header; for 410 and 411 files this | |
932 | is the length of the header plus the size of the text portion. | |
933 | .PP | |
934 | The "b" and "e" fields are the starting and ending locations | |
935 | for a segment. | |
936 | Given an address, A, the location in | |
937 | the file (either \fIa.out\fP or \fIcore\fP) is calculated as: | |
938 | .P1 | |
939 | b1\(<=A\(<=e1 =\h'-.5m'> file address = (A\-b1)+f1 | |
940 | b2\(<=A\(<=e2 =\h'-.5m'> file address = (A\-b2)+f2 | |
941 | .P2 | |
942 | A user can access locations by using the ADB defined variables. | |
943 | The \fB$v\fR request prints the variables initialized by ADB: | |
944 | .P1 | |
945 | b base address of data segment | |
946 | d length of the data segment | |
947 | s length of the stack | |
948 | t length of the text | |
949 | m execution type (407,410,411) | |
950 | .P2 | |
951 | .PP | |
952 | In Figure 9 those variables not present are zero. | |
953 | Use can be made of these variables by expressions such as: | |
954 | .P1 | |
955 | <b | |
956 | .P2 | |
957 | in the address field. | |
958 | Similarly the value of the variable can be changed by an assignment request | |
959 | such as: | |
960 | .P1 | |
961 | 02000>b | |
962 | .P2 | |
963 | that sets \fBb\fP to octal 2000. | |
964 | These variables are useful to know if the file under examination | |
965 | is an executable or \fIcore\fP image file. | |
966 | .PP | |
967 | ADB reads the header of the \fIcore\fP image file to find the | |
968 | values for these variables. | |
969 | If the second file specified does not | |
970 | seem to be a \fIcore\fP file, or if it is missing then the header of | |
971 | the executable file is used instead. | |
972 | .NH | |
973 | Advanced Usage | |
974 | .PP | |
975 | It is possible with ADB to combine formatting requests | |
976 | to provide elaborate displays. | |
977 | Below are several examples. | |
978 | .NH 2 | |
979 | Formatted dump | |
980 | .PP | |
981 | The line: | |
982 | .P1 | |
983 | <b,\-1/4o4^8Cn | |
984 | .P2 | |
985 | prints 4 octal words followed by their ASCII interpretation | |
986 | from the data space of the core image file. | |
987 | Broken down, the various request pieces mean: | |
988 | .sp | |
989 | .in 1.7i | |
990 | .ta .7i | |
991 | .ti -.7i | |
992 | <b The base address of the data segment. | |
993 | .sp | |
994 | .ti -.7i | |
995 | <b,\-1 Print from the base address to the end of file. | |
996 | A negative count is used here and elsewhere to loop indefinitely | |
997 | or until some error condition (like end of file) is detected. | |
998 | .sp | |
999 | .ti -1.7i | |
1000 | The format \fB4o4^8Cn\fR is broken down as follows: | |
1001 | .sp | |
1002 | .ti -.7i | |
1003 | 4o Print 4 octal locations. | |
1004 | .sp | |
1005 | .ti -.7i | |
1006 | 4^ Backup the current address 4 locations (to the original start of the field). | |
1007 | .sp | |
1008 | .ti -.7i | |
1009 | 8C Print 8 consecutive characters using an escape convention; | |
1010 | each character in the range 0 to 037 is printed as @ followed by the corresponding character in the range 0140 to 0177. | |
1011 | An @ is printed as @@. | |
1012 | .sp | |
1013 | .ti -.7i | |
1014 | n Print a newline. | |
1015 | .in -1.7i | |
1016 | .fi | |
1017 | .sp | |
1018 | .PP | |
1019 | The request: | |
1020 | .P1 | |
1021 | <b,<d/4o4^8Cn | |
1022 | .P2 | |
1023 | could have been used instead to allow the printing to stop | |
1024 | at the end of the data segment (<d provides the data segment size in bytes). | |
1025 | .PP | |
1026 | The formatting requests can be combined with ADB's ability | |
1027 | to read in a script to produce a core image dump script. | |
1028 | ADB is invoked as: | |
1029 | .P1 | |
1030 | adb a.out core < dump | |
1031 | .P2 | |
1032 | to read in a script file, | |
1033 | .ul | |
1034 | dump, | |
1035 | of requests. | |
1036 | An example of such a script is: | |
1037 | .P1 | |
1038 | 120$w | |
1039 | 4095$s | |
1040 | $v | |
1041 | =3n | |
1042 | $m | |
1043 | =3n"C Stack Backtrace" | |
1044 | $C | |
1045 | =3n"C External Variables" | |
1046 | $e | |
1047 | =3n"Registers" | |
1048 | $r | |
1049 | 0$s | |
1050 | =3n"Data Segment" | |
1051 | <b,\-1/8ona | |
1052 | .P2 | |
1053 | .PP | |
1054 | The request \fB120$w\fP sets the width of the output to | |
1055 | 120 characters | |
1056 | (normally, the width is 80 characters). | |
1057 | ADB attempts to print addresses as: | |
1058 | .P1 | |
1059 | symbol + offset | |
1060 | .P2 | |
1061 | The request \fB4095$s\fP increases the maximum permissible offset | |
1062 | to the nearest symbolic address from 255 (default) to 4095. | |
1063 | The request \fB=\fP can be used to print literal strings. | |
1064 | Thus, | |
1065 | headings are provided in this | |
1066 | .ul | |
1067 | dump | |
1068 | program | |
1069 | with requests of the form: | |
1070 | .P1 | |
1071 | =3n"C Stack Backtrace" | |
1072 | .P2 | |
1073 | that spaces three lines and prints the literal | |
1074 | string. | |
1075 | The request \fB$v\fP prints all non-zero ADB variables (see Figure 8). | |
1076 | The request | |
1077 | \fB0$s\fP | |
1078 | sets the maximum offset for symbol matches to zero thus | |
1079 | suppressing the printing of symbolic labels in favor | |
1080 | of octal values. | |
1081 | Note that this is only done for the printing of the data segment. | |
1082 | The request: | |
1083 | .P1 | |
1084 | <b,\-1/8ona | |
1085 | .P2 | |
1086 | prints a dump from the base of the data segment to the end of file | |
1087 | with an octal address field and eight octal numbers per line. | |
1088 | .PP | |
1089 | Figure 11 shows the results of some formatting requests | |
1090 | on the C program of Figure 10. | |
1091 | .NH 2 | |
1092 | Directory Dump | |
1093 | .PP | |
1094 | As another illustration (Figure 12) consider a set of requests to dump | |
1095 | the contents of a directory (which is made up | |
1096 | of an integer \fIinumber\fP followed by a 14 character name): | |
1097 | .P1 | |
1098 | adb dir \- | |
1099 | =n8t"Inum"8t"Name" | |
1100 | 0,\-1? u8t14cn | |
1101 | .P2 | |
1102 | In this example, the \fBu\fP prints the \fIinumber\fP as an unsigned decimal integer, | |
1103 | the \fB8t\fP means that ADB will space to the next | |
1104 | multiple of 8 on the output line, and the \fB14c\fP prints the 14 character file name. | |
1105 | .NH 2 | |
1106 | Ilist Dump | |
1107 | .PP | |
1108 | Similarly the contents of the \fIilist\fP of a file system, (e.g. /dev/src, | |
1109 | on UNIX systems distributed by the UNIX Support Group; | |
1110 | see UNIX Programmer's | |
1111 | Manual Section V) could be dumped with the following set of | |
1112 | requests: | |
1113 | .P1 | |
1114 | adb /dev/src \- | |
1115 | 02000>b | |
1116 | ?m <b | |
1117 | <b,\-1?"flags"8ton"links,uid,gid"8t3bn",size"8tbrdn"addr"8t8un"times"8t2Y2na | |
1118 | .P2 | |
1119 | In this example the value of the base for the map was changed | |
1120 | to 02000 (by saying \fB?m<b\fR) since that is the start of an \fIilist\fP within a file system. | |
1121 | An artifice (\fBbrd\fP above) was used to print the 24 bit size field | |
1122 | as a byte, a space, and a decimal integer. | |
1123 | The last access time and last modify time are printed with the | |
1124 | \fB2Y\fR | |
1125 | operator. | |
1126 | Figure 12 shows portions of these requests as applied to a directory | |
1127 | and file system. | |
1128 | .NH 2 | |
1129 | Converting values | |
1130 | .PP | |
1131 | ADB may be used to convert values from one representation to | |
1132 | another. | |
1133 | For example: | |
1134 | .P1 | |
1135 | 072 = odx | |
1136 | .P2 | |
1137 | will print | |
1138 | .P1 | |
1139 | 072 58 #3a | |
1140 | .P2 | |
1141 | which is the octal, decimal and hexadecimal representations | |
1142 | of 072 (octal). | |
1143 | The format is remembered so that typing | |
1144 | subsequent numbers will print them in the given formats. | |
1145 | Character values may be converted similarly, for example: | |
1146 | .P1 | |
1147 | 'a' = co | |
1148 | .P2 | |
1149 | prints | |
1150 | .P1 | |
1151 | a 0141 | |
1152 | .P2 | |
1153 | It may also be used to evaluate expressions but be | |
1154 | warned that all binary operators have | |
1155 | the same precedence which is lower than that for unary operators. | |
1156 | .NH | |
1157 | Patching | |
1158 | .PP | |
1159 | Patching files with ADB is accomplished with the | |
1160 | .ul | |
1161 | write, | |
1162 | \fBw\fP or \fBW\fP, request (which is not like the \fIed\fP editor write command). | |
1163 | This is often used in conjunction with the | |
1164 | .ul | |
1165 | locate, | |
1166 | \fBl\fP or \fBL\fP | |
1167 | request. | |
1168 | In general, the request syntax for \fBl\fP and \fBw\fP are similar as follows: | |
1169 | .P1 | |
1170 | ?l value | |
1171 | .P2 | |
1172 | The request \fBl\fP is used to match on two bytes, \fBL\fP is used for | |
1173 | four bytes. | |
1174 | The request \fBw\fP is used to write two bytes, whereas | |
1175 | \fBW\fP writes four bytes. | |
1176 | The \fBvalue\fP field in either | |
1177 | .ul | |
1178 | locate | |
1179 | or | |
1180 | .ul | |
1181 | write | |
1182 | requests | |
1183 | is an expression. | |
1184 | Therefore, decimal and octal numbers, or character strings are supported. | |
1185 | .PP | |
1186 | In order to modify a file, ADB must be called as: | |
1187 | .P1 | |
1188 | adb \-w file1 file2 | |
1189 | .P2 | |
1190 | When called with this option, | |
1191 | .ul | |
1192 | file1 | |
1193 | and | |
1194 | .ul | |
1195 | file2 | |
1196 | are created if necessary and opened for both reading and writing. | |
1197 | .PP | |
1198 | For example, consider the C program shown in Figure 10. | |
1199 | We can change the word "This" to "The " in the executable file | |
1200 | for this program, \fIex7\fP, by using the following requests: | |
1201 | .P1 | |
1202 | adb \-w ex7 \- | |
1203 | ?l 'Th' | |
1204 | ?W 'The ' | |
1205 | .P2 | |
1206 | The request \fB?l\fP starts at dot and stops at the first match of "Th" | |
1207 | having set dot to the address of the location found. | |
1208 | Note the use of \fB?\fP to write to the | |
1209 | .ul | |
1210 | a.out | |
1211 | file. | |
1212 | The form \fB?*\fP would have been used for a 411 file. | |
1213 | .PP | |
1214 | More frequently the | |
1215 | request will be typed as: | |
1216 | .P1 | |
1217 | ?l 'Th'; ?s | |
1218 | .P2 | |
1219 | and locates the first occurrence of "Th" and print the entire string. | |
1220 | Execution of this ADB request will set dot to the address of the | |
1221 | "Th" characters. | |
1222 | .PP | |
1223 | As another example of the utility of the patching facility, | |
1224 | consider a C program that has an internal logic flag. | |
1225 | The flag could be set by the user through ADB and the program run. | |
1226 | For example: | |
1227 | .P1 | |
1228 | adb a.out \- | |
1229 | :s arg1 arg2 | |
1230 | flag/w 1 | |
1231 | :c | |
1232 | .P2 | |
1233 | The \fB:s\fR request is normally used to single step through a process | |
1234 | or start a process in single step mode. | |
1235 | In this case it starts | |
1236 | .ul | |
1237 | a.out | |
1238 | as a subprocess | |
1239 | with arguments \fBarg1\fP and \fBarg2\fP. | |
1240 | If there is a subprocess running ADB writes to it rather than to the file | |
1241 | so the \fBw\fP request causes \fIflag\fP to be changed in the memory of the subprocess. | |
1242 | .NH | |
1243 | Anomalies | |
1244 | .PP | |
1245 | Below is a list of some strange things that users | |
1246 | should be aware of. | |
1247 | .IP 1. | |
1248 | Function calls and arguments are put on the stack by the C | |
1249 | save routine. | |
1250 | Putting breakpoints at the entry point to routines | |
1251 | means that the function appears not to have been called | |
1252 | when the | |
1253 | breakpoint occurs. | |
1254 | .IP 2. | |
1255 | When printing addresses, ADB uses | |
1256 | either text or data symbols from the \fIa.out\fP file. | |
1257 | This sometimes causes unexpected symbol names to be printed | |
1258 | with data (e.g. \fIsavr5+022\fP). | |
1259 | This does not happen if | |
1260 | \fB?\fR is used for text (instructions) | |
1261 | and \fB/\fP for data. | |
1262 | .IP 3. | |
1263 | ADB cannot handle C register variables | |
1264 | in the most recently activated function. | |
1265 | .LP | |
1266 | .NH | |
1267 | Acknowledgements | |
1268 | .PP | |
1269 | The authors are grateful for the thoughtful comments | |
1270 | on how to organize this document | |
1271 | from R. B. Brandt, E. N. Pinson and B. A. Tague. | |
1272 | D. M. Ritchie made the system changes necessary to accommodate | |
1273 | tracing within ADB. He also participated in discussions | |
1274 | during the writing of ADB. | |
1275 | His earlier work with DB and CDB led to many of the | |
1276 | features found in ADB. | |
1277 | .SG MH-8234-JFM/1273-SRB-unix | |
1278 | .NH | |
1279 | References | |
1280 | .LP | |
1281 | .IP 1. | |
1282 | D. M. Ritchie and K. Thompson, | |
1283 | ``The UNIX Time-Sharing System,'' | |
1284 | CACM, July, 1974. | |
1285 | .IP 2. | |
1286 | B. W. Kernighan and D. M. Ritchie, | |
1287 | .ul | |
1288 | The C Programming Language, | |
1289 | Prentice-Hall, 1978. | |
1290 | .IP 3. | |
1291 | K. Thompson and D. M. Ritchie, | |
1292 | UNIX Programmer's Manual - 7th Edition, | |
1293 | 1978. | |
1294 | .IP 4. | |
1295 | B. W. Kernighan and P. J. Plauger, | |
1296 | .ul | |
1297 | Software Tools, | |
1298 | Addison-Wesley, 1976. | |
1299 | .sp 100 | |
1300 | .nr PS 9 | |
1301 | .nr VS 11 | |
1302 | . \" START OF Figures | |
1303 | .de P1 | |
1304 | .nf | |
1305 | .in +.5i | |
1306 | .ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i | |
1307 | .sp | |
1308 | .ps 9 | |
1309 | .vs 11p | |
1310 | .. | |
1311 | .de P2 | |
1312 | .sp | |
1313 | .fi | |
1314 | .ps \\n(PS | |
1315 | .vs \\n(VS | |
1316 | .in -.5i | |
1317 | .. | |
1318 | .SH | |
1319 | Figure 1: C program with pointer bug | |
1320 | .LP | |
1321 | .P1 | |
1322 | struct buf { | |
1323 | int fildes; | |
1324 | int nleft; | |
1325 | char *nextp; | |
1326 | char buff[512]; | |
1327 | }bb; | |
1328 | struct buf *obuf; | |
1329 | ||
1330 | char *charp "this is a sentence."; | |
1331 | ||
1332 | main(argc,argv) | |
1333 | int argc; | |
1334 | char **argv; | |
1335 | { | |
1336 | char cc; | |
1337 | ||
1338 | if(argc < 2) { | |
1339 | printf("Input file missing\\n"); | |
1340 | exit(8); | |
1341 | } | |
1342 | ||
1343 | if((fcreat(argv[1],obuf)) < 0){ | |
1344 | printf("%s : not found\\n", argv[1]); | |
1345 | exit(8); | |
1346 | } | |
1347 | charp = \'T\'; | |
1348 | printf("debug 1 %s\\n",charp); | |
1349 | while(cc= *charp++) | |
1350 | putc(cc,obuf); | |
1351 | fflush(obuf); | |
1352 | } | |
1353 | .P2 | |
1354 | .sp 100 | |
1355 | .SH | |
1356 | Figure 2: ADB output for C program of Figure 1 | |
1357 | .LP | |
1358 | .P1 | |
1359 | .ft B | |
1360 | adb a.out core | |
1361 | $c | |
1362 | .ft R | |
1363 | ~main(02,0177762) | |
1364 | .ft B | |
1365 | $C | |
1366 | .ft R | |
1367 | ~main(02,0177762) | |
1368 | argc: 02 | |
1369 | argv: 0177762 | |
1370 | cc: 02124 | |
1371 | .ft B | |
1372 | $r | |
1373 | .ft R | |
1374 | ps 0170010 | |
1375 | pc 0204 ~main+0152 | |
1376 | sp 0177740 | |
1377 | r5 0177752 | |
1378 | r4 01 | |
1379 | r3 0 | |
1380 | r2 0 | |
1381 | r1 0 | |
1382 | r0 0124 | |
1383 | ~main+0152: mov _obuf,(sp) | |
1384 | .ft B | |
1385 | $e | |
1386 | .ft R | |
1387 | savr5: 0 | |
1388 | _obuf: 0 | |
1389 | _charp: 0124 | |
1390 | _errno: 0 | |
1391 | _fout: 0 | |
1392 | .ft B | |
1393 | $m | |
1394 | .ft R | |
1395 | text map \`ex1\' | |
1396 | b1 = 0 e1 = 02360 f1 = 020 | |
1397 | b2 = 0 e2 = 02360 f2 = 020 | |
1398 | data map \`core1\' | |
1399 | b1 = 0 e1 = 03500 f1 = 02000 | |
1400 | b2 = 0175400 e2 = 0200000 f2 = 05500 | |
1401 | .ft B | |
1402 | *charp/s | |
1403 | .ft R | |
1404 | 0124: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\1dL\ 3x\7f \ 3N\1dh\ 4@\1dx\7f&\10_ | |
1405 | ~ | |
1406 | .ft B | |
1407 | charp/s | |
1408 | .ft R | |
1409 | _charp: T | |
1410 | ||
1411 | _charp+02: this is a sentence. | |
1412 | ||
1413 | _charp+026: Input file missing | |
1414 | .ft B | |
1415 | main.argc/d | |
1416 | .ft R | |
1417 | 0177756: 2 | |
1418 | .ft B | |
1419 | *main.argv/3o | |
1420 | .ft R | |
1421 | 0177762: 0177770 0177776 0177777 | |
1422 | .ft B | |
1423 | 0177770/s | |
1424 | .ft R | |
1425 | 0177770: a.out | |
1426 | .ft B | |
1427 | *main.argv/3o | |
1428 | .ft R | |
1429 | 0177762: 0177770 0177776 0177777 | |
1430 | .ft B | |
1431 | *"/s | |
1432 | .ft R | |
1433 | 0177770: a.out | |
1434 | .ft B | |
1435 | .=o | |
1436 | .ft R | |
1437 | 0177770 | |
1438 | .ft B | |
1439 | .\(mi10/d | |
1440 | .ft R | |
1441 | 0177756: 2 | |
1442 | .ft B | |
1443 | $q | |
1444 | .P2 | |
1445 | .sp 100 | |
1446 | .SH | |
1447 | Figure 3: Multiple function C program for stack trace illustration | |
1448 | .LP | |
1449 | .P1 | |
1450 | int fcnt,gcnt,hcnt; | |
1451 | h(x,y) | |
1452 | { | |
1453 | int hi; register int hr; | |
1454 | hi = x+1; | |
1455 | hr = x\(miy+1; | |
1456 | hcnt++ ; | |
1457 | hj: | |
1458 | f(hr,hi); | |
1459 | } | |
1460 | ||
1461 | g(p,q) | |
1462 | { | |
1463 | int gi; register int gr; | |
1464 | gi = q\(mip; | |
1465 | gr = q\(mip+1; | |
1466 | gcnt++ ; | |
1467 | gj: | |
1468 | h(gr,gi); | |
1469 | } | |
1470 | ||
1471 | f(a,b) | |
1472 | { | |
1473 | int fi; register int fr; | |
1474 | fi = a+2*b; | |
1475 | fr = a+b; | |
1476 | fcnt++ ; | |
1477 | fj: | |
1478 | g(fr,fi); | |
1479 | } | |
1480 | ||
1481 | main() | |
1482 | { | |
1483 | f(1,1); | |
1484 | } | |
1485 | .P2 | |
1486 | .sp 100 | |
1487 | .SH | |
1488 | Figure 4: ADB output for C program of Figure 3 | |
1489 | .LP | |
1490 | .P1 | |
1491 | .ft B | |
1492 | adb | |
1493 | $c | |
1494 | .ft R | |
1495 | ~h(04452,04451) | |
1496 | ~g(04453,011124) | |
1497 | ~f(02,04451) | |
1498 | ~h(04450,04447) | |
1499 | ~g(04451,011120) | |
1500 | ~f(02,04447) | |
1501 | ~h(04446,04445) | |
1502 | ~g(04447,011114) | |
1503 | ~f(02,04445) | |
1504 | ~h(04444,04443) | |
1505 | .ft B | |
1506 | HIT DEL KEY | |
1507 | .ft R | |
1508 | adb | |
1509 | .ft B | |
1510 | ,5$C | |
1511 | .ft R | |
1512 | ~h(04452,04451) | |
1513 | x: 04452 | |
1514 | y: 04451 | |
1515 | hi: ? | |
1516 | ~g(04453,011124) | |
1517 | p: 04453 | |
1518 | q: 011124 | |
1519 | gi: 04451 | |
1520 | gr: ? | |
1521 | ~f(02,04451) | |
1522 | a: 02 | |
1523 | b: 04451 | |
1524 | fi: 011124 | |
1525 | fr: 04453 | |
1526 | ~h(04450,04447) | |
1527 | x: 04450 | |
1528 | y: 04447 | |
1529 | hi: 04451 | |
1530 | hr: 02 | |
1531 | ~g(04451,011120) | |
1532 | p: 04451 | |
1533 | q: 011120 | |
1534 | gi: 04447 | |
1535 | gr: 04450 | |
1536 | .ft B | |
1537 | fcnt/d | |
1538 | .ft R | |
1539 | _fcnt: 1173 | |
1540 | .ft B | |
1541 | gcnt/d | |
1542 | .ft R | |
1543 | _gcnt: 1173 | |
1544 | .ft B | |
1545 | hcnt/d | |
1546 | .ft R | |
1547 | _hcnt: 1172 | |
1548 | .ft B | |
1549 | h.x/d | |
1550 | .ft R | |
1551 | 022004: 2346 | |
1552 | .ft B | |
1553 | $q | |
1554 | .P2 | |
1555 | .sp 100 | |
1556 | .SH | |
1557 | Figure 5: C program to decode tabs | |
1558 | .LP | |
1559 | .P1 | |
1560 | #define MAXLINE 80 | |
1561 | #define YES 1 | |
1562 | #define NO 0 | |
1563 | #define TABSP 8 | |
1564 | .sp .5 | |
1565 | char input[] "data"; | |
1566 | char ibuf[518]; | |
1567 | int tabs[MAXLINE]; | |
1568 | .sp .5 | |
1569 | main() | |
1570 | { | |
1571 | int col, *ptab; | |
1572 | char c; | |
1573 | .sp .5 | |
1574 | ptab = tabs; | |
1575 | settab(ptab); /*Set initial tab stops */ | |
1576 | col = 1; | |
1577 | if(fopen(input,ibuf) < 0) { | |
1578 | printf("%s : not found\\n",input); | |
1579 | exit(8); | |
1580 | } | |
1581 | while((c = getc(ibuf)) != \(mi1) { | |
1582 | switch(c) { | |
1583 | case \(fm\\t\(fm: /* TAB */ | |
1584 | while(tabpos(col) != YES) { | |
1585 | putchar(\(fm \(fm); /* put BLANK */ | |
1586 | col++ ; | |
1587 | } | |
1588 | break; | |
1589 | case \(fm\\n\(fm: /*NEWLINE */ | |
1590 | putchar(\(fm\\n\(fm); | |
1591 | col = 1; | |
1592 | break; | |
1593 | default: | |
1594 | putchar(c); | |
1595 | col++ ; | |
1596 | } | |
1597 | } | |
1598 | } | |
1599 | .sp .5 | |
1600 | /* Tabpos return YES if col is a tab stop */ | |
1601 | tabpos(col) | |
1602 | int col; | |
1603 | { | |
1604 | if(col > MAXLINE) | |
1605 | return(YES); | |
1606 | else | |
1607 | return(tabs[col]); | |
1608 | } | |
1609 | .sp .5 | |
1610 | /* Settab - Set initial tab stops */ | |
1611 | settab(tabp) | |
1612 | int *tabp; | |
1613 | { | |
1614 | int i; | |
1615 | .sp .5 | |
1616 | for(i = 0; i<= MAXLINE; i++) | |
1617 | (i%TABSP) ? (tabs[i] = NO) : (tabs[i] = YES); | |
1618 | } | |
1619 | .P2 | |
1620 | .sp 100 | |
1621 | .SH | |
1622 | Figure 6a: ADB output for C program of Figure 5 | |
1623 | .LP | |
1624 | .P1 | |
1625 | .ft B | |
1626 | adb a.out \(mi | |
1627 | settab+4:b | |
1628 | fopen+4:b | |
1629 | getc+4:b | |
1630 | tabpos+4:b | |
1631 | $b | |
1632 | .ft R | |
1633 | breakpoints | |
1634 | count bkpt command | |
1635 | 1 ~tabpos+04 | |
1636 | 1 _getc+04 | |
1637 | 1 _fopen+04 | |
1638 | 1 ~settab+04 | |
1639 | .ft B | |
1640 | settab,5?ia | |
1641 | .ft R | |
1642 | ~settab: jsr r5,csv | |
1643 | ~settab+04: tst \(mi(sp) | |
1644 | ~settab+06: clr 0177770(r5) | |
1645 | ~settab+012: cmp $0120,0177770(r5) | |
1646 | ~settab+020: blt ~settab+076 | |
1647 | ~settab+022: | |
1648 | .ft B | |
1649 | settab,5?i | |
1650 | .ft R | |
1651 | ~settab: jsr r5,csv | |
1652 | tst \(mi(sp) | |
1653 | clr 0177770(r5) | |
1654 | cmp $0120,0177770(r5) | |
1655 | blt ~settab+076 | |
1656 | .ft B | |
1657 | :r | |
1658 | .ft R | |
1659 | a.out: running | |
1660 | breakpoint ~settab+04: tst \(mi(sp) | |
1661 | .ft B | |
1662 | settab+4:d | |
1663 | :c | |
1664 | .ft R | |
1665 | a.out: running | |
1666 | breakpoint _fopen+04: mov 04(r5),nulstr+012 | |
1667 | .ft B | |
1668 | $C | |
1669 | .ft R | |
1670 | _fopen(02302,02472) | |
1671 | ~main(01,0177770) | |
1672 | col: 01 | |
1673 | c: 0 | |
1674 | ptab: 03500 | |
1675 | .ft B | |
1676 | tabs,3/8o | |
1677 | .ft R | |
1678 | 03500: 01 0 0 0 0 0 0 0 | |
1679 | 01 0 0 0 0 0 0 0 | |
1680 | 01 0 0 0 0 0 0 0 | |
1681 | .P2 | |
1682 | .sp 100 | |
1683 | .SH | |
1684 | Figure 6b: ADB output for C program of Figure 5 | |
1685 | .LP | |
1686 | .P1 | |
1687 | .ft B | |
1688 | :c | |
1689 | .ft R | |
1690 | a.out: running | |
1691 | breakpoint _getc+04: mov 04(r5),r1 | |
1692 | .ft B | |
1693 | ibuf+6/20c | |
1694 | .ft R | |
1695 | __cleanu+0202: This is a test of | |
1696 | .ft B | |
1697 | :c | |
1698 | .ft R | |
1699 | a.out: running | |
1700 | breakpoint ~tabpos+04: cmp $0120,04(r5) | |
1701 | .ft B | |
1702 | tabpos+4:d | |
1703 | settab+4:b settab,5?ia | |
1704 | settab+4:b settab,5?ia; 0 | |
1705 | getc+4,3:b main.c?C; 0 | |
1706 | settab+4:b settab,5?ia; ptab/o; 0 | |
1707 | $b | |
1708 | .ft R | |
1709 | breakpoints | |
1710 | count bkpt command | |
1711 | 1 ~tabpos+04 | |
1712 | 3 _getc+04 main.c?C;0 | |
1713 | 1 _fopen+04 | |
1714 | 1 ~settab+04 settab,5?ia;ptab?o;0 | |
1715 | ~settab: jsr r5,csv | |
1716 | ~settab+04: bpt | |
1717 | ~settab+06: clr 0177770(r5) | |
1718 | ~settab+012: cmp $0120,0177770(r5) | |
1719 | ~settab+020: blt ~settab+076 | |
1720 | ~settab+022: | |
1721 | 0177766: 0177770 | |
1722 | 0177744: @\` | |
1723 | T0177744: T | |
1724 | h0177744: h | |
1725 | i0177744: i | |
1726 | s0177744: s | |
1727 | .P2 | |
1728 | .sp 100 | |
1729 | .SH | |
1730 | Figure 7: ADB output for C program with breakpoints | |
1731 | .LP | |
1732 | .in +.5i | |
1733 | .nf | |
1734 | .ps 8 | |
1735 | .vs 9 | |
1736 | .ft B | |
1737 | adb ex3 \(mi | |
1738 | h+4:b hcnt/d; h.hi/; h.hr/ | |
1739 | g+4:b gcnt/d; g.gi/; g.gr/ | |
1740 | f+4:b fcnt/d; f.fi/; f.fr/ | |
1741 | :r | |
1742 | .ft R | |
1743 | ex3: running | |
1744 | _fcnt: 0 | |
1745 | 0177732: 214 | |
1746 | symbol not found | |
1747 | .ft B | |
1748 | f+4:b fcnt/d; f.a/; f.b/; f.fi/ | |
1749 | g+4:b gcnt/d; g.p/; g.q/; g.gi/ | |
1750 | h+4:b hcnt/d; h.x/; h.y/; h.hi/ | |
1751 | :c | |
1752 | .ft R | |
1753 | ex3: running | |
1754 | _fcnt: 0 | |
1755 | 0177746: 1 | |
1756 | 0177750: 1 | |
1757 | 0177732: 214 | |
1758 | _gcnt: 0 | |
1759 | 0177726: 2 | |
1760 | 0177730: 3 | |
1761 | 0177712: 214 | |
1762 | _hcnt: 0 | |
1763 | 0177706: 2 | |
1764 | 0177710: 1 | |
1765 | 0177672: 214 | |
1766 | _fcnt: 1 | |
1767 | 0177666: 2 | |
1768 | 0177670: 3 | |
1769 | 0177652: 214 | |
1770 | _gcnt: 1 | |
1771 | 0177646: 5 | |
1772 | 0177650: 8 | |
1773 | 0177632: 214 | |
1774 | .ft B | |
1775 | HIT DEL | |
1776 | f+4:b fcnt/d; f.a/"a = "d; f.b/"b = "d; f.fi/"fi = "d | |
1777 | g+4:b gcnt/d; g.p/"p = "d; g.q/"q = "d; g.gi/"gi = "d | |
1778 | h+4:b hcnt/d; h.x/"x = "d; h.y/"h = "d; h.hi/"hi = "d | |
1779 | :r | |
1780 | .ft R | |
1781 | ex3: running | |
1782 | _fcnt: 0 | |
1783 | 0177746: a = 1 | |
1784 | 0177750: b = 1 | |
1785 | 0177732: fi = 214 | |
1786 | _gcnt: 0 | |
1787 | 0177726: p = 2 | |
1788 | 0177730: q = 3 | |
1789 | 0177712: gi = 214 | |
1790 | _hcnt: 0 | |
1791 | 0177706: x = 2 | |
1792 | 0177710: y = 1 | |
1793 | 0177672: hi = 214 | |
1794 | _fcnt: 1 | |
1795 | 0177666: a = 2 | |
1796 | 0177670: b = 3 | |
1797 | 0177652: fi = 214 | |
1798 | .ft B | |
1799 | HIT DEL | |
1800 | $q | |
1801 | .in -.5i | |
1802 | .sp 100 | |
1803 | .SH | |
1804 | Figure 8: ADB address maps | |
1805 | .LP | |
1806 | .de l1 | |
1807 | .tc | |
1808 | .ta 1.20i +1.6i +2.5i | |
1809 | .. | |
1810 | .de l3 | |
1811 | .tc | |
1812 | .ta 1.6i +2.80i +.2i +1.55i | |
1813 | .. | |
1814 | .de l2 | |
1815 | .tc | |
1816 | .ti 1.0i | |
1817 | .ta +0.5i +3.0i +1.75i | |
1818 | .tc _ | |
1819 | .. | |
1820 | .de l5 | |
1821 | .tc | |
1822 | .ti 1.0i | |
1823 | .ta +0.75i +3.0i +1.5i | |
1824 | .tc _ | |
1825 | .. | |
1826 | .de l6 | |
1827 | .tc | |
1828 | .ti 1.0i | |
1829 | .ta +.8i +2.85i +0.4i +1.1i | |
1830 | .. | |
1831 | .de l8 | |
1832 | .tc | |
1833 | .ti 1.0i | |
1834 | .ta +0.5i +3.0i +1.75i | |
1835 | .tc _ | |
1836 | .. | |
1837 | .de la | |
1838 | .tc | |
1839 | .ta 1.20i +1.25i +1.7i | |
1840 | .. | |
1841 | .de lc | |
1842 | .tc | |
1843 | .ti 1.0i | |
1844 | .ta +.85i +1.6i +.35i +1.1i | |
1845 | .. | |
1846 | .de lb | |
1847 | .tc | |
1848 | .ti 1.0i | |
1849 | .ta +0.75i +1.75i +1.5i | |
1850 | .tc _ | |
1851 | .. | |
1852 | .ul | |
1853 | 407 files | |
1854 | .sp | |
1855 | .l1 | |
1856 | a.out hdr text+data | |
1857 | .l2 | |
1858 | | | | | |
1859 | .l3 | |
1860 | 0 D | |
1861 | .sp | |
1862 | .l1 | |
1863 | core hdr text+data stack | |
1864 | .l5 | |
1865 | | | ......| | | |
1866 | .l6 | |
1867 | 0 D S E | |
1868 | .sp 2 | |
1869 | .ul | |
1870 | 410 files (shared text) | |
1871 | .sp | |
1872 | .l1 | |
1873 | a.out hdr text data | |
1874 | .l2 | |
1875 | | | | | | |
1876 | .l3 | |
1877 | 0 T B D | |
1878 | .sp | |
1879 | .la | |
1880 | core hdr data stack | |
1881 | .lb | |
1882 | | | ......| | | |
1883 | .lc | |
1884 | B D S E | |
1885 | .sp 2 | |
1886 | .ul | |
1887 | 411 files (separated I and D space) | |
1888 | .sp | |
1889 | .l1 | |
1890 | a.out hdr text data | |
1891 | .l2 | |
1892 | | | | | | |
1893 | .l3 | |
1894 | 0 T 0 D | |
1895 | .sp | |
1896 | .la | |
1897 | core hdr data stack | |
1898 | .lb | |
1899 | | | ......| | | |
1900 | .lc | |
1901 | 0 D S E | |
1902 | .sp 2 | |
1903 | The following | |
1904 | .ul | |
1905 | adb | |
1906 | variables are set. | |
1907 | .nf | |
1908 | .ta .75i 1.5i 3.5i 4.5i 5.5i | |
1909 | .sp | |
1910 | 407 410 411 | |
1911 | .sp | |
1912 | b base of data 0 B 0 | |
1913 | d length of data D D\(miB D | |
1914 | s length of stack S S S | |
1915 | t length of text 0 T T | |
1916 | .sp 100 | |
1917 | .SH | |
1918 | Figure 9: ADB output for maps | |
1919 | .LP | |
1920 | .nf | |
1921 | .in +.5i | |
1922 | .ft B | |
1923 | adb map407 core407 | |
1924 | $m | |
1925 | .ft R | |
1926 | text map \`map407\' | |
1927 | b1 = 0 e1 = 0256 f1 = 020 | |
1928 | b2 = 0 e2 = 0256 f2 = 020 | |
1929 | data map \`core407\' | |
1930 | b1 = 0 e1 = 0300 f1 = 02000 | |
1931 | b2 = 0175400 e2 = 0200000 f2 = 02300 | |
1932 | .ft B | |
1933 | $v | |
1934 | .ft R | |
1935 | variables | |
1936 | d = 0300 | |
1937 | m = 0407 | |
1938 | s = 02400 | |
1939 | .ft B | |
1940 | $q | |
1941 | .sp 2 | |
1942 | adb map410 core410 | |
1943 | $m | |
1944 | .ft R | |
1945 | text map \`map410\' | |
1946 | b1 = 0 e1 = 0200 f1 = 020 | |
1947 | b2 = 020000 e2 = 020116 f2 = 0220 | |
1948 | data map \`core410\' | |
1949 | b1 = 020000 e1 = 020200 f1 = 02000 | |
1950 | b2 = 0175400 e2 = 0200000 f2 = 02200 | |
1951 | .ft B | |
1952 | $v | |
1953 | .ft R | |
1954 | variables | |
1955 | b = 020000 | |
1956 | d = 0200 | |
1957 | m = 0410 | |
1958 | s = 02400 | |
1959 | t = 0200 | |
1960 | .ft B | |
1961 | $q | |
1962 | .sp 2 | |
1963 | adb map411 core411 | |
1964 | $m | |
1965 | .ft R | |
1966 | text map \`map411\' | |
1967 | b1 = 0 e1 = 0200 f1 = 020 | |
1968 | b2 = 0 e2 = 0116 f2 = 0220 | |
1969 | data map \`core411\' | |
1970 | b1 = 0 e1 = 0200 f1 = 02000 | |
1971 | b2 = 0175400 e2 = 0200000 f2 = 02200 | |
1972 | .ft B | |
1973 | $v | |
1974 | .ft R | |
1975 | variables | |
1976 | d = 0200 | |
1977 | m = 0411 | |
1978 | s = 02400 | |
1979 | t = 0200 | |
1980 | .ft B | |
1981 | $q | |
1982 | .in -.5i | |
1983 | .sp 100 | |
1984 | .SH | |
1985 | Figure 10: Simple C program for illustrating formatting and patching | |
1986 | .LP | |
1987 | .P1 | |
1988 | char str1[] "This is a character string"; | |
1989 | int one 1; | |
1990 | int number 456; | |
1991 | long lnum 1234; | |
1992 | float fpt 1.25; | |
1993 | char str2[] "This is the second character string"; | |
1994 | main() | |
1995 | { | |
1996 | one = 2; | |
1997 | } | |
1998 | .P2 | |
1999 | .sp 100 | |
2000 | .SH | |
2001 | Figure 11: ADB output illustrating fancy formats | |
2002 | .LP | |
2003 | .nf | |
2004 | .ps 9 | |
2005 | .vs 11p | |
2006 | .ft B | |
2007 | adb map410 core410 | |
2008 | <b,\(mi1/8ona | |
2009 | .ft R | |
2010 | 020000: 0 064124 071551 064440 020163 020141 064143 071141 | |
2011 | .sp .5 | |
2012 | _str1+016: 061541 062564 020162 072163 064562 063556 0 02 | |
2013 | .sp .5 | |
2014 | _number: | |
2015 | _number: 0710 0 02322 040240 0 064124 071551 064440 | |
2016 | .sp .5 | |
2017 | _str2+06: 020163 064164 020145 062563 067543 062156 061440 060550 | |
2018 | .sp .5 | |
2019 | _str2+026: 060562 072143 071145 071440 071164 067151 0147 0 | |
2020 | .sp .5 | |
2021 | savr5+02: 0 0 0 0 0 0 0 0 | |
2022 | .sp .5 | |
2023 | .ft B | |
2024 | <b,20/4o4^8Cn | |
2025 | .ft R | |
2026 | 020000: 0 064124 071551 064440 @\`@\`This i | |
2027 | 020163 020141 064143 071141 s a char | |
2028 | 061541 062564 020162 072163 acter st | |
2029 | 064562 063556 0 02 ring@\`@\`@b@\` | |
2030 | .sp .5 | |
2031 | _number: 0710 0 02322 040240 H@a@\`@\`R@d @@ | |
2032 | 0 064124 071551 064440 @\`@\`This i | |
2033 | 020163 064164 020145 062563 s the se | |
2034 | 067543 062156 061440 060550 cond cha | |
2035 | 060562 072143 071145 071440 racter s | |
2036 | 071164 067151 0147 0 tring@\`@\`@\` | |
2037 | 0 0 0 0 @\`@\`@\`@\`@\`@\`@\`@\` | |
2038 | 0 0 0 0 @\`@\`@\`@\`@\`@\`@\`@\` | |
2039 | data address not found | |
2040 | .ft B | |
2041 | <b,20/4o4^8t8cna | |
2042 | .ft R | |
2043 | 020000: 0 064124 071551 064440 This i | |
2044 | _str1+06: 020163 020141 064143 071141 s a char | |
2045 | _str1+016: 061541 062564 020162 072163 acter st | |
2046 | _str1+026: 064562 063556 0 02 ring\ 2 | |
2047 | _number: | |
2048 | _number: 0710 0 02322 040240 HR | |
2049 | _fpt+02: 0 064124 071551 064440 This i | |
2050 | _str2+06: 020163 064164 020145 062563 s the se | |
2051 | _str2+016: 067543 062156 061440 060550 cond cha | |
2052 | _str2+026: 060562 072143 071145 071440 racter s | |
2053 | _str2+036: 071164 067151 0147 0 tring | |
2054 | savr5+02: 0 0 0 0 | |
2055 | savr5+012: 0 0 0 0 | |
2056 | data address not found | |
2057 | .ft B | |
2058 | <b,10/2b8t^2cn | |
2059 | .ft R | |
2060 | 020000: 0 0 | |
2061 | .sp .5 | |
2062 | _str1: 0124 0150 Th | |
2063 | 0151 0163 is | |
2064 | 040 0151 i | |
2065 | 0163 040 s | |
2066 | 0141 040 a | |
2067 | 0143 0150 ch | |
2068 | 0141 0162 ar | |
2069 | 0141 0143 ac | |
2070 | 0164 0145 te | |
2071 | .ft B | |
2072 | $Q | |
2073 | .sp 100 | |
2074 | .SH | |
2075 | Figure 12: Directory and inode dumps | |
2076 | .LP | |
2077 | .nf | |
2078 | .ft B | |
2079 | adb dir \(mi | |
2080 | =nt"Inode"t"Name" | |
2081 | 0,\(mi1?ut14cn | |
2082 | .ft R | |
2083 | ||
2084 | Inode Name | |
2085 | 0: 652 . | |
2086 | 82 .. | |
2087 | 5971 cap.c | |
2088 | 5323 cap | |
2089 | 0 pp | |
2090 | .sp 4 | |
2091 | .ft B | |
2092 | adb /dev/src \(mi | |
2093 | .ft B | |
2094 | 02000>b | |
2095 | ?m<b | |
2096 | .ft R | |
2097 | new map \`/dev/src\' | |
2098 | b1 = 02000 e1 = 0100000000 f1 = 0 | |
2099 | b2 = 0 e2 = 0 f2 = 0 | |
2100 | .ft B | |
2101 | $v | |
2102 | .ft R | |
2103 | variables | |
2104 | b = 02000 | |
2105 | .ft B | |
2106 | <b,\(mi1?"flags"8ton"links,uid,gid"8t3bn"size"8tbrdn"addr"8t8un"times"8t2Y2na | |
2107 | .ft R | |
2108 | 02000: flags 073145 | |
2109 | links,uid,gid 0163 0164 0141 | |
2110 | size 0162 10356 | |
2111 | addr 28770 8236 25956 27766 25455 8236 25956 25206 | |
2112 | times 1976 Feb 5 08:34:56 1975 Dec 28 10:55:15 | |
2113 | ||
2114 | 02040: flags 024555 | |
2115 | links,uid,gid 012 0163 0164 | |
2116 | size 0162 25461 | |
2117 | addr 8308 30050 8294 25130 15216 26890 29806 10784 | |
2118 | times 1976 Aug 17 12:16:51 1976 Aug 17 12:16:51 | |
2119 | ||
2120 | 02100: flags 05173 | |
2121 | links,uid,gid 011 0162 0145 | |
2122 | size 0147 29545 | |
2123 | addr 25972 8306 28265 8308 25642 15216 2314 25970 | |
2124 | times 1977 Apr 2 08:58:01 1977 Feb 5 10:21:44 | |
2125 | .\" | |
2126 | .\" Start of Summary | |
2127 | .sp 100 | |
2128 | .TL | |
2129 | ADB Summary | |
2130 | .LP | |
2131 | .LP | |
2132 | .if t .2C | |
2133 | .nr VS 9 | |
2134 | .nr VS 11 | |
2135 | .SH | |
2136 | Command Summary | |
2137 | .LP | |
2138 | .ta .7i | |
2139 | a) formatted printing | |
2140 | .sp .5 | |
2141 | .IP "\fB? \fIformat\fR" .7i | |
2142 | print from \fIa.out\fR file according to \fIformat\fR | |
2143 | .IP "\fB/ \fIformat\fR" .7i | |
2144 | print from \fIcore\fR file according to \fIformat\fR | |
2145 | .IP "\fB= \fIformat\fR" .7i | |
2146 | print the value of \fIdot\fR | |
2147 | .sp .5 | |
2148 | .IP "\fB?w\fR expr" .7i | |
2149 | write expression into \fIa.out\fR file | |
2150 | .IP "\fB/w\fR expr" .7i | |
2151 | write expression into \fIcore\fR file | |
2152 | .sp .5 | |
2153 | .IP "\fB?l\fR expr" .7i | |
2154 | locate expression in \fIa.out\fR file | |
2155 | .LP | |
2156 | .ta .7i | |
2157 | b) breakpoint and program control | |
2158 | .LP | |
2159 | .ta .7i | |
2160 | .nf | |
2161 | .ta .7i | |
2162 | \fB:b\fR set breakpoint at \fIdot\fR | |
2163 | \fB:c\fR continue running program | |
2164 | \fB:d\fR delete breakpoint | |
2165 | \fB:k\fR kill the program being debugged | |
2166 | \fB:r\fR run \fIa.out\fR file under ADB control | |
2167 | \fB:s\fR single step | |
2168 | .LP | |
2169 | .ta .7i | |
2170 | c) miscellaneous printing | |
2171 | .LP | |
2172 | .ta .7i | |
2173 | .nf | |
2174 | \fB$b\fR print current breakpoints | |
2175 | \fB$c\fR C stack trace | |
2176 | \fB$e\fR external variables | |
2177 | \fB$f\fR floating registers | |
2178 | \fB$m\fR print ADB segment maps | |
2179 | \fB$q\fR exit from ADB | |
2180 | \fB$r\fR general registers | |
2181 | \fB$s\fR set offset for symbol match | |
2182 | \fB$v\fR print ADB variables | |
2183 | \fB$w\fR set output line width | |
2184 | .LP | |
2185 | .ta .7i | |
2186 | d) calling the shell | |
2187 | .LP | |
2188 | .ta .7i | |
2189 | .nf | |
2190 | \fB!\fR call \fIshell\fP to read rest of line | |
2191 | .LP | |
2192 | .ta .7i | |
2193 | e) assignment to variables | |
2194 | .LP | |
2195 | .ta .7i | |
2196 | .nf | |
2197 | \fB>\fIname\fR assign dot to variable or register \fIname\fR | |
2198 | .sp 100 | |
2199 | .SH | |
2200 | Format Summary | |
2201 | .LP | |
2202 | .ta .7i | |
2203 | .nf | |
2204 | \fBa \fRthe value of dot | |
2205 | \fBb \fRone byte in octal | |
2206 | \fBc \fRone byte as a character | |
2207 | \fBd \fRone word in decimal | |
2208 | \fBf \fRtwo words in floating point | |
2209 | \fBi \fRPDP 11 instruction | |
2210 | \fBo \fRone word in octal | |
2211 | \fBn \fRprint a newline | |
2212 | \fBr \fRprint a blank space | |
2213 | \fBs \fRa null terminated character string | |
2214 | \fIn\fBt \fRmove to next \fIn\fR space tab | |
2215 | \fBu \fRone word as unsigned integer | |
2216 | \fBx \fRhexadecimal | |
2217 | \fBY \fRdate | |
2218 | \fB^ \fRbackup dot | |
2219 | \fB"..."\fR print string | |
2220 | .LP | |
2221 | .ta .7i | |
2222 | .SH | |
2223 | Expression Summary | |
2224 | .LP | |
2225 | .ta .7i | |
2226 | a) expression components | |
2227 | .LP | |
2228 | .ta .1.1i | |
2229 | .nf | |
2230 | \fBdecimal integer \fRe.g. 256 | |
2231 | \fBoctal integer \fRe.g. 0277 | |
2232 | \fBhexadecimal \fRe.g. #ff | |
2233 | \fBsymbols \fRe.g. flag _main main.argc | |
2234 | \fBvariables \fRe.g. <b | |
2235 | \fBregisters \fRe.g. <pc <r0 | |
2236 | \fB(expression) \fRexpression grouping | |
2237 | .LP | |
2238 | .ta .7i | |
2239 | b) dyadic operators | |
2240 | .LP | |
2241 | .ta .7i | |
2242 | .nf | |
2243 | \fB+\fP add | |
2244 | \fB\(mi\fP subtract | |
2245 | \fB*\fP multiply | |
2246 | \fB%\fP integer division | |
2247 | \fB&\fP bitwise and | |
2248 | \fB|\fP bitwise or | |
2249 | \fB#\fP round up to the next multiple | |
2250 | .LP | |
2251 | .ta .7i | |
2252 | c) monadic operators | |
2253 | .LP | |
2254 | .ta .7i | |
2255 | .nf | |
2256 | \v'.25m'\s+2\fB~\fP\s0\v'-.25m' not | |
2257 | \fB*\fR contents of location | |
2258 | \fB\(mi\fR integer negate | |
2259 | .fi |