new copyright; att/bsd/shared
[unix-history] / usr / src / old / adb / PSD.doc / adb.ms
CommitLineData
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
23A Tutorial Introduction to ADB
24.AU "MH2F-207" "3816"
25J. F. Maranzano
26.AU "MH2C-512" 7419
27S. R. Bourne
28.AI
29.MH
30.OK
31.\"UNIX
32.\"Debugging
33.\"C Programming
34.AB
35.PP
36Debugging tools generally provide a wealth of information
37about the inner workings of programs.
38These tools have been available on
39.UX
40to allow users to
41examine ``core'' files
42that result from aborted programs.
43A new debugging program, ADB, provides enhanced capabilities
44to examine "core" and other program files in a
45variety of formats, run programs with embedded breakpoints and patch files.
46.PP
47ADB is an indispensable but complex tool for debugging crashed systems and/or
48programs.
49This document provides an introduction to ADB with examples of its use.
50It explains the various formatting options,
51techniques for debugging C programs, examples of printing
52file system information and patching.
53.AE
54.CS 12 15 27 13 0 5
55.NH
56Introduction
57.PP
58ADB is a new debugging program that is
59available on UNIX.
60It provides capabilities to look at
61``core'' files resulting from aborted programs, print output in a
62variety of formats, patch files, and run programs
63with embedded breakpoints.
64This document provides examples of
65the more useful features of ADB.
66The reader is expected to be
67familiar with the basic commands on
68.UX
69with the C
70language, and with References 1, 2 and 3.
71.NH
72A Quick Survey
73.NH 2
74Invocation
75.PP
76ADB is invoked as:
77.P1
78 adb objfile corefile
79.P2
80where
81.ul
82objfile
83is an executable UNIX file and
84.ul
85corefile
86is a core image file.
87Many times this will look like:
88.P1
89 adb a.out core
90.P2
91or more simply:
92.P1
93 adb
94.P2
95where the defaults are
96.ul
97a.out
98and
99.ul
100core
101respectively.
102The filename minus (\-) means ignore this argument as in:
103.P1
104 adb \- core
105.P2
106.PP
107ADB has requests for examining locations in either file.
108The
109\fB?\fP
110request examines the contents of
111.ul
112objfile,
113the
114\fB/\fP
115request examines the
116.ul
117corefile.
118The general form of these requests is:
119.P1
120 address ? format
121.P2
122or
123.P1
124 address / format
125.P2
126.NH 2
127Current Address
128.PP
129ADB maintains a current address, called dot,
130similar in function to the current pointer in the UNIX editor.
131When an address is entered, the current address is set to that location,
132so that:
133.P1
134 0126?i
135.P2
136sets dot to octal 126 and prints the instruction
137at that address.
138The request:
139.P1
140 .,10/d
141.P2
142prints 10 decimal numbers starting at dot.
143Dot ends up referring to the address of the last item printed.
144When used with the \fB?\fP or \fB/\fP requests,
145the current address can be advanced by typing newline; it can be decremented
146by typing \fB^\fP.
147.PP
148Addresses are represented by
149expressions.
150Expressions are made up from decimal, octal, and hexadecimal integers,
151and symbols from the program under test.
152These may be combined with the operators +, \-, *, % (integer division),
153& (bitwise and), | (bitwise inclusive or), # (round up
154to the next multiple), and ~ (not).
155(All arithmetic within ADB is 32 bits.)
156When typing a symbolic address for a C program,
157the user can type
158.ul
159name
160or
161.ul
162_name;
163ADB will recognize both forms.
164.NH 2
165Formats
166.PP
167To print data, a user specifies a collection of letters and characters
168that describe the format of the printout.
169Formats are "remembered" in the sense that typing a request without one
170will cause the new printout to appear in the previous format.
171The 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,
187for example, `\fBD\fR' for long decimal, and `\fBF\fP' for double floating point.)
188For other formats see the ADB manual.
189.NH 2
190General Request Meanings
191.PP
192The general form of a request is:
193.P1
194 address,count command modifier
195.P2
196which sets `dot' to \fIaddress\fP
197and executes the command
198\fIcount\fR times.
199.PP
200The 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
212ADB catches signals, so a user cannot use a quit signal to exit from ADB.
213The request $q or $Q (or cntl-D) must be used
214to exit from ADB.
215.NH
216Debugging C Programs
217.NH 2
218Debugging A Core Image
219.PP
220Consider the C program in Figure 1.
221The program is used to illustrate a common error made by
222C programmers.
223The object of the program is to change the
224lower case "t" to upper case in the string pointed to by
225.ul
226charp
227and then write the character string to the file indicated by
228argument 1.
229The bug shown is that the character "T"
230is stored in the pointer
231.ul
232charp
233instead of the string pointed to by
234.ul
235charp.
236Executing the program produces a core file because of an out of bounds memory reference.
237.PP
238ADB is invoked by:
239.P1
240 adb a.out core
241.P2
242The first debugging request:
243.P1
244 $c
245.P2
246is used to give a C backtrace through the
247subroutines called.
248As shown in Figure 2
249only one function (\fImain\fR) was called and the
250arguments
251.ul
252argc
253and
254.ul
255argv
256have octal values 02 and
2570177762 respectively.
258Both of these values look
259reasonable; 02 = two arguments, 0177762 = address on stack
260of parameter vector.
261.br
262The next request:
263.P1
264 $C
265.P2
266is used to give a C backtrace plus an interpretation
267of all the local variables in each function and their
268values in octal.
269The value of the variable
270.ul
271cc
272looks incorrect
273since
274.ul
275cc
276was declared as a character.
277.PP
278The next request:
279.P1
280 $r
281.P2
282prints out the registers including the program
283counter and an interpretation of the instruction at that
284location.
285.PP
286The request:
287.P1
288 $e
289.P2
290prints out the values of all external variables.
291.PP
292A map exists for each file
293handled by
294ADB.
295The map for the
296.ul
297a.out
298file is referenced by \fB?\fP whereas the map for
299.ul
300core
301file is referenced by \fB/\fP.
302Furthermore, a good rule of thumb is to use \fB?\fP for
303instructions and \fB/\fP for data when looking at programs.
304To print out information about the maps type:
305.P1
306 $m
307.P2
308This produces a report of the contents of the maps.
309More about these maps later.
310.PP
311In our example, it is useful to see the
312contents of the string pointed to by
313.ul
314charp.
315This is done by:
316.P1
317 *charp/s
318.P2
319which says use
320.ul
321charp
322as a pointer in the
323.ul
324core
325file
326and print the information as a character string.
327This printout clearly shows that the character buffer
328was incorrectly overwritten and helps identify the error.
329Printing the locations around
330.ul
331charp
332shows that the buffer is unchanged
333but that the pointer is destroyed.
334Using ADB similarly, we could print information about the
335arguments to a function.
336The request:
337.P1
338 main.argc/d
339.P2
340prints the decimal
341.ul
342core
343image value of the argument
344.ul
345argc
346in the function
347.ul
348main.
349.br
350The request:
351.P1
352 *main.argv,3/o
353.P2
354prints the octal values of the three consecutive
355cells pointed to by
356.ul
357argv
358in the function
359.ul
360main.
361Note that these values are the addresses of the arguments
362to main.
363Therefore:
364.P1
365 0177770/s
366.P2
367prints the ASCII value of the first argument.
368Another way to print this value would have been
369.P1
370 *"/s
371.P2
372The " means ditto which remembers the last address
373typed, in this case \fImain.argc\fP ; the \fB*\fP instructs ADB to use the address field of the
374.ul
375core
376file as a pointer.
377.PP
378The request:
379.P1
380 .=o
381.P2
382prints the current address (not its contents) in octal which has been set to the address of the first argument.
383The current address, dot, is used by ADB to
384"remember" its current location.
385It allows the user
386to reference locations relative to the current
387address, for example:
388.P1
389 .\-10/d
390.P2
391.NH 2
392Multiple Functions
393.PP
394Consider the C program illustrated in
395Figure 3.
396This program calls functions
397.ul
398f, g,
399and
400.ul
401h
402until the stack is exhausted and a core image is produced.
403.PP
404Again you can enter the debugger via:
405.P1
406 adb
407.P2
408which assumes the names
409.ul
410a.out
411and
412.ul
413core
414for the executable
415file and core image file respectively.
416The request:
417.P1
418 $c
419.P2
420will fill a page of backtrace references to
421.ul
422f, g,
423and
424.ul
425h.
426Figure 4 shows an abbreviated list (typing
427.ul
428DEL
429will terminate the output and bring you back to ADB request level).
430.PP
431The request:
432.P1
433 ,5$C
434.P2
435prints the five most recent activations.
436.PP
437Notice that each function
438(\fIf,g,h\fP) has a counter
439of the number of times it was called.
440.PP
441The request:
442.P1
443 fcnt/d
444.P2
445prints the decimal value of the counter for the function
446.ul
447f.
448Similarly
449.ul
450gcnt
451and
452.ul
453hcnt
454could be printed.
455To print the value of an automatic variable,
456for example the decimal value of
457.ul
458x
459in the last call of the function
460.ul
461h,
462type:
463.P1
464 h.x/d
465.P2
466It is currently not possible in the exported version to print stack frames other than the most recent activation of a function.
467Therefore, a user can print everything with
468\fB$C\fR or the occurrence of a variable in the most recent call of a function.
469It is possible with the \fB$C\fR request, however, to print the stack frame
470starting at some address as \fBaddress$C.\fR
471.NH 2
472Setting Breakpoints
473.PP
474Consider the C program in Figure 5.
475This program, which changes tabs into blanks, is adapted from
476.ul
477Software Tools
478by Kernighan and Plauger, pp. 18-27.
479.PP
480We will run this program under the control of ADB (see Figure 6a) by:
481.P1
482 adb a.out \-
483.P2
484Breakpoints are set in the program as:
485.ul
486.P1
487 address:b [request]
488.P2
489The requests:
490.P1
491 settab+4:b
492 fopen+4:b
493 getc+4:b
494 tabpos+4:b
495.P2
496set breakpoints at the start of these functions.
497C does not generate statement labels.
498Therefore it is currently not possible to plant breakpoints at locations
499other than function entry points without a knowledge of the code
500generated by the C compiler.
501The above addresses are entered as
502.ft B
503symbol+4
504.ft R
505so that they will appear in any
506C backtrace since the first instruction of each function is a call
507to the C save routine
508(\fIcsv\fR).
509Note that some of the functions are from the C library.
510.PP
511To print the location of breakpoints one types:
512.P1
513 $b
514.P2
515The display indicates a
516.ul
517count
518field.
519A breakpoint is bypassed
520.ul
521count \-1
522times before causing a stop.
523The
524.ul
525command
526field indicates the ADB requests to be executed each time the breakpoint is encountered.
527In our example no
528.ul
529command
530fields are present.
531.PP
532By displaying the original instructions at the function
533.ul
534settab
535we see that
536the breakpoint is set after the jsr to the C save routine.
537We can display the instructions using the ADB request:
538.P1
539 settab,5?ia
540.P2
541This request displays five instructions starting at
542.ul
543settab
544with the addresses of each location displayed.
545Another variation is:
546.P1
547 settab,5?i
548.P2
549which displays the instructions with only the starting address.
550.PP
551Notice that we accessed the addresses from the
552.ul
553a.out
554file with the \fB?\fP command.
555In general when asking for a printout of multiple items,
556ADB will advance the current address the number of
557bytes necessary to satisfy the request; in the above
558example five instructions were displayed and the current address was
559advanced 18 (decimal) bytes.
560.PP
561To run the program one simply types:
562.P1
563 :r
564.P2
565To delete a breakpoint, for instance the entry to the function
566.ul
567settab,
568one types:
569.P1
570 settab+4:d
571.P2
572To continue execution of the program from the breakpoint type:
573.P1
574 :c
575.PP
576Once the program has stopped (in this case at the breakpoint for
577.ul
578fopen),
579ADB requests can be used to display the contents of memory.
580For example:
581.P1
582 $C
583.P2
584to display a stack trace, or:
585.P1
586 tabs,3/8o
587.P2
588to print three lines of 8 locations each from the array called
589.ul
590tabs.
591By this time (at location
592.ul
593fopen)
594in the C program,
595.ul
596settab
597has been called and should have set a one in every eighth location of
598.ul
599tabs.
600.NH 2
601Advanced Breakpoint Usage
602.PP
603We continue execution of the program with:
604.P1
605 :c
606.P2
607See Figure 6b.
608.ul
609Getc
610is called three times and the contents of the variable
611.ul
612c
613in the function
614.ul
615main
616are displayed
617each time.
618The single character on the left hand edge is the output from the C program.
619On the third occurrence of
620.ul
621getc
622the program stops.
623We can look at the full buffer of characters by typing:
624.P1
625 ibuf+6/20c
626.P2
627When we continue the program with:
628.P1
629 :c
630.P2
631we hit our first breakpoint at
632.ul
633tabpos
634since there is a tab following the
635"This" word of the data.
636.PP
637Several breakpoints of
638.ul
639tabpos
640will occur until the program has changed the tab into equivalent blanks.
641Since we feel that
642.ul
643tabpos
644is working,
645we can remove the breakpoint at that location by:
646.P1
647 tabpos+4:d
648.P2
649If the program is continued with:
650.P1
651 :c
652.P2
653it resumes normal execution after ADB prints
654the message
655.P1
656 a.out:running
657.P2
658.PP
659The UNIX quit and interrupt signals
660act on ADB itself rather than on the program being debugged.
661If such a signal occurs then the program being debugged is stopped and control is returned to ADB.
662The signal is saved by ADB and is passed on to the test program if:
663.P1
664 :c
665.P2
666is typed.
667This can be useful when testing interrupt
668handling routines.
669The signal is not passed on to the test program if:
670.P1
671 :c 0
672.P2
673is typed.
674.PP
675Now let us reset the breakpoint at
676.ul
677settab
678and display the instructions located there when we reach the breakpoint.
679This 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
685version distributed in Generic 3 UNIX) these statements
686must be written as:
687.br
688.in 1i
689\fBsettab+4:b settab,5?ia;0\fR
690.ft B
691.br
692getc+4,3:b main.c?C;0
693.br
694settab+4:b settab,5?ia; ptab/o;0
695.br
696.ft R
697.in -1i
698Note that \fB;0\fR will set dot to zero and stop at the breakpoint.
699.FE
700It is also possible to execute the ADB requests for each occurrence of the breakpoint but
701only stop after the third occurrence by typing:
702.P1
703 getc+4,3:b main.c?C \fR*
704.P2
705This request will print the local variable
706.ul
707c
708in the function
709.ul
710main
711at each occurrence of the breakpoint.
712The semicolon is used to separate multiple ADB requests on a single line.
713.PP
714Warning:
715setting a breakpoint causes the value of dot to be changed;
716executing the program under ADB does not change dot.
717Therefore:
718.P1
719 settab+4:b .,5?ia
720 fopen+4:b
721.P2
722will print the last thing dot was set to
723(in the example \fIfopen+4\fP)
724.ul
725not
726the current location (\fIsettab+4\fP)
727at which the program is executing.
728.PP
729A breakpoint can be overwritten without first deleting the old breakpoint.
730For example:
731.P1
732 settab+4:b settab,5?ia; ptab/o \fR*
733.P2
734could be entered after typing the above requests.
735.PP
736Now the display of breakpoints:
737.P1
738 $b
739.P2
740shows the above request for the
741.ul
742settab
743breakpoint.
744When the breakpoint at
745.ul
746settab
747is encountered the ADB requests are executed.
748Note that the location at
749.ul
750settab+4
751has been changed to plant the breakpoint;
752all the other locations match their original value.
753.PP
754Using the functions,
755.ul
756f, g
757and
758.ul
759h
760shown in Figure 3,
761we can follow the execution of each function by planting non-stopping
762breakpoints.
763We call ADB with the executable program of Figure 3 as follows:
764.P1
765 adb ex3 \-
766.P2
767Suppose 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
774Each request line indicates that the variables are printed in decimal
775(by the specification \fBd\fR).
776Since the format is not changed, the \fBd\fR can be left off all but
777the first request.
778.PP
779The output in Figure 7 illustrates two points.
780First, the ADB requests in the breakpoint line are not
781examined until the program under
782test is run.
783That means any errors in those ADB requests is not detected until run time.
784At the location of the error ADB stops running the program.
785.PP
786The second point is the way ADB handles register variables.
787ADB uses the symbol table to address variables.
788Register variables, like \fIf.fr\fR above, have pointers to uninitialized
789places on the stack.
790Therefore the message "symbol not found".
791.PP
792Another way of getting at the data in this example is to print
793the 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
799The operator / was used instead of ?
800to read values from the \fIcore\fP file.
801The output for each function, as shown in Figure 7, has the same format.
802For the function \fIf\fP, for example, it shows the name and value of the
803.ul
804external
805variable
806.ul
807fcnt.
808It also shows the address on the stack and value of the
809variables
810.ul
811a, b
812and
813.ul
814fi.
815.PP
816Notice that the addresses on the stack will continue to decrease
817until no address space is left for program execution
818at which time (after many pages of output)
819the program under test aborts.
820A 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
824In this format the quoted string is printed literally and the \fBd\fP
825produces a decimal display of the variables.
826The results are shown in Figure 7.
827.NH 2
828Other Breakpoint Facilities
829.LP
830.IP \(bu 4
831Arguments and change of standard input and output are passed to a program as:
832.P1
833 :r arg1 arg2 ... <infile >outfile
834.P2
835This request
836kills any existing program under test and
837starts the
838.ul
839a.out
840afresh.
841.IP \(bu
842The program being debugged can be single stepped
843by:
844.P1
845 :s
846.P2
847If necessary, this request will start up the program being
848debugged and stop after executing
849the first instruction.
850.IP \(bu
851ADB allows a program to be entered at a specific address
852by typing:
853.P1
854 address:r
855.P2
856.IP \(bu
857The count field can be used to skip the first \fIn\fR breakpoints as:
858.P1
859 ,n:r
860.P2
861The request:
862.P1
863 ,n:c
864.P2
865may also be used for skipping the first \fIn\fR breakpoints
866when continuing a program.
867.sp
868.IP \(bu
869A program can be continued at an address different from the breakpoint by:
870.P1
871 address:c
872.P2
873.IP \(bu
874The program being debugged runs as a separate process and can be killed by:
875.P1
876 :k
877.P2
878.LP
879.NH
880Maps
881.PP
882UNIX supports several executable file formats. These are used to tell
883the loader how to load the program file. File type 407
884is the most common and is generated by a C compiler invocation such as
885\fBcc pgm.c\fP.
886A 410 file is produced by a C compiler command of the form \fBcc -n pgm.c\fP,
887whereas a 411 file is produced by \fBcc -i pgm.c\fP.
888ADB interprets these different file formats and
889provides access to the different segments through a set of maps (see Figure 8).
890To print the maps type:
891.P1
892 $m
893.P2
894.PP
895In 407 files, both text (instructions) and data are intermixed.
896This makes it impossible for ADB to differentiate data from
897instructions and some of the printed symbolic addresses look incorrect;
898for example, printing data addresses as offsets from routines.
899.PP
900In 410 files (shared text), the instructions are separated from data and
901\fB?*\fR accesses the data part of the \fIa.out\fP file.
902The \fB?* \fP request tells ADB to use the second part of the
903map in the
904.ul
905a.out
906file.
907Accessing data in the \fIcore\fP file shows
908the data after it was modified by the execution of the program.
909Notice also that the data segment may have grown during
910program execution.
911.PP
912In 411 files (separated I & D space), the
913instructions and data are also separated.
914However, in this
915case, since data is mapped through a separate set of segmentation
916registers, the base of the data segment is also relative to address zero.
917In this case since the addresses overlap it is necessary to use
918the \fB?*\fR operator to access the data space of the \fIa.out\fP file.
919In both 410 and 411 files the corresponding
920core file does not contain the program text.
921.PP
922Figure 9 shows the display of three maps
923for the same program linked as a 407, 410, 411 respectively.
924The b, e, and f fields are used by ADB to map
925addresses into file addresses.
926The "f1" field is the
927length of the header at the beginning of the file (020 bytes
928for an \fIa.out\fP file and 02000 bytes for a \fIcore\fP file).
929The "f2" field is the displacement from the beginning of the file to the data.
930For a 407 file with mixed text and data this is the
931same as the length of the header; for 410 and 411 files this
932is the length of the header plus the size of the text portion.
933.PP
934The "b" and "e" fields are the starting and ending locations
935for a segment.
936Given an address, A, the location in
937the 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
942A user can access locations by using the ADB defined variables.
943The \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
952In Figure 9 those variables not present are zero.
953Use can be made of these variables by expressions such as:
954.P1
955 <b
956.P2
957in the address field.
958Similarly the value of the variable can be changed by an assignment request
959such as:
960.P1
961 02000>b
962.P2
963that sets \fBb\fP to octal 2000.
964These variables are useful to know if the file under examination
965is an executable or \fIcore\fP image file.
966.PP
967ADB reads the header of the \fIcore\fP image file to find the
968values for these variables.
969If the second file specified does not
970seem to be a \fIcore\fP file, or if it is missing then the header of
971the executable file is used instead.
972.NH
973Advanced Usage
974.PP
975It is possible with ADB to combine formatting requests
976to provide elaborate displays.
977Below are several examples.
978.NH 2
979Formatted dump
980.PP
981The line:
982.P1
983 <b,\-1/4o4^8Cn
984.P2
985prints 4 octal words followed by their ASCII interpretation
986from the data space of the core image file.
987Broken 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.
996A negative count is used here and elsewhere to loop indefinitely
997or until some error condition (like end of file) is detected.
998.sp
999.ti -1.7i
1000The format \fB4o4^8Cn\fR is broken down as follows:
1001.sp
1002.ti -.7i
10034o Print 4 octal locations.
1004.sp
1005.ti -.7i
10064^ Backup the current address 4 locations (to the original start of the field).
1007.sp
1008.ti -.7i
10098C Print 8 consecutive characters using an escape convention;
1010each character in the range 0 to 037 is printed as @ followed by the corresponding character in the range 0140 to 0177.
1011An @ is printed as @@.
1012.sp
1013.ti -.7i
1014n Print a newline.
1015.in -1.7i
1016.fi
1017.sp
1018.PP
1019The request:
1020.P1
1021 <b,<d/4o4^8Cn
1022.P2
1023could have been used instead to allow the printing to stop
1024at the end of the data segment (<d provides the data segment size in bytes).
1025.PP
1026The formatting requests can be combined with ADB's ability
1027to read in a script to produce a core image dump script.
1028ADB is invoked as:
1029.P1
1030 adb a.out core < dump
1031.P2
1032to read in a script file,
1033.ul
1034dump,
1035of requests.
1036An 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
1054The request \fB120$w\fP sets the width of the output to
1055120 characters
1056(normally, the width is 80 characters).
1057ADB attempts to print addresses as:
1058.P1
1059 symbol + offset
1060.P2
1061The request \fB4095$s\fP increases the maximum permissible offset
1062to the nearest symbolic address from 255 (default) to 4095.
1063The request \fB=\fP can be used to print literal strings.
1064Thus,
1065headings are provided in this
1066.ul
1067dump
1068program
1069with requests of the form:
1070.P1
1071 =3n"C Stack Backtrace"
1072.P2
1073that spaces three lines and prints the literal
1074string.
1075The request \fB$v\fP prints all non-zero ADB variables (see Figure 8).
1076The request
1077\fB0$s\fP
1078sets the maximum offset for symbol matches to zero thus
1079suppressing the printing of symbolic labels in favor
1080of octal values.
1081Note that this is only done for the printing of the data segment.
1082The request:
1083.P1
1084 <b,\-1/8ona
1085.P2
1086prints a dump from the base of the data segment to the end of file
1087with an octal address field and eight octal numbers per line.
1088.PP
1089Figure 11 shows the results of some formatting requests
1090on the C program of Figure 10.
1091.NH 2
1092Directory Dump
1093.PP
1094As another illustration (Figure 12) consider a set of requests to dump
1095the contents of a directory (which is made up
1096of 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
1102In this example, the \fBu\fP prints the \fIinumber\fP as an unsigned decimal integer,
1103the \fB8t\fP means that ADB will space to the next
1104multiple of 8 on the output line, and the \fB14c\fP prints the 14 character file name.
1105.NH 2
1106Ilist Dump
1107.PP
1108Similarly the contents of the \fIilist\fP of a file system, (e.g. /dev/src,
1109on UNIX systems distributed by the UNIX Support Group;
1110see UNIX Programmer's
1111Manual Section V) could be dumped with the following set of
1112requests:
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
1119In this example the value of the base for the map was changed
1120to 02000 (by saying \fB?m<b\fR) since that is the start of an \fIilist\fP within a file system.
1121An artifice (\fBbrd\fP above) was used to print the 24 bit size field
1122as a byte, a space, and a decimal integer.
1123The last access time and last modify time are printed with the
1124\fB2Y\fR
1125operator.
1126Figure 12 shows portions of these requests as applied to a directory
1127and file system.
1128.NH 2
1129Converting values
1130.PP
1131ADB may be used to convert values from one representation to
1132another.
1133For example:
1134.P1
1135 072 = odx
1136.P2
1137will print
1138.P1
1139 072 58 #3a
1140.P2
1141which is the octal, decimal and hexadecimal representations
1142of 072 (octal).
1143The format is remembered so that typing
1144subsequent numbers will print them in the given formats.
1145Character values may be converted similarly, for example:
1146.P1
1147 'a' = co
1148.P2
1149prints
1150.P1
1151 a 0141
1152.P2
1153It may also be used to evaluate expressions but be
1154warned that all binary operators have
1155the same precedence which is lower than that for unary operators.
1156.NH
1157Patching
1158.PP
1159Patching files with ADB is accomplished with the
1160.ul
1161write,
1162\fBw\fP or \fBW\fP, request (which is not like the \fIed\fP editor write command).
1163This is often used in conjunction with the
1164.ul
1165locate,
1166\fBl\fP or \fBL\fP
1167request.
1168In general, the request syntax for \fBl\fP and \fBw\fP are similar as follows:
1169.P1
1170 ?l value
1171.P2
1172The request \fBl\fP is used to match on two bytes, \fBL\fP is used for
1173four bytes.
1174The request \fBw\fP is used to write two bytes, whereas
1175\fBW\fP writes four bytes.
1176The \fBvalue\fP field in either
1177.ul
1178locate
1179or
1180.ul
1181write
1182requests
1183is an expression.
1184Therefore, decimal and octal numbers, or character strings are supported.
1185.PP
1186In order to modify a file, ADB must be called as:
1187.P1
1188 adb \-w file1 file2
1189.P2
1190When called with this option,
1191.ul
1192file1
1193and
1194.ul
1195file2
1196are created if necessary and opened for both reading and writing.
1197.PP
1198For example, consider the C program shown in Figure 10.
1199We can change the word "This" to "The " in the executable file
1200for this program, \fIex7\fP, by using the following requests:
1201.P1
1202 adb \-w ex7 \-
1203 ?l 'Th'
1204 ?W 'The '
1205.P2
1206The request \fB?l\fP starts at dot and stops at the first match of "Th"
1207having set dot to the address of the location found.
1208Note the use of \fB?\fP to write to the
1209.ul
1210a.out
1211file.
1212The form \fB?*\fP would have been used for a 411 file.
1213.PP
1214More frequently the
1215request will be typed as:
1216.P1
1217 ?l 'Th'; ?s
1218.P2
1219and locates the first occurrence of "Th" and print the entire string.
1220Execution of this ADB request will set dot to the address of the
1221"Th" characters.
1222.PP
1223As another example of the utility of the patching facility,
1224consider a C program that has an internal logic flag.
1225The flag could be set by the user through ADB and the program run.
1226For example:
1227.P1
1228 adb a.out \-
1229 :s arg1 arg2
1230 flag/w 1
1231 :c
1232.P2
1233The \fB:s\fR request is normally used to single step through a process
1234or start a process in single step mode.
1235In this case it starts
1236.ul
1237a.out
1238as a subprocess
1239with arguments \fBarg1\fP and \fBarg2\fP.
1240If there is a subprocess running ADB writes to it rather than to the file
1241so the \fBw\fP request causes \fIflag\fP to be changed in the memory of the subprocess.
1242.NH
1243Anomalies
1244.PP
1245Below is a list of some strange things that users
1246should be aware of.
1247.IP 1.
1248Function calls and arguments are put on the stack by the C
1249save routine.
1250Putting breakpoints at the entry point to routines
1251means that the function appears not to have been called
1252when the
1253breakpoint occurs.
1254.IP 2.
1255When printing addresses, ADB uses
1256either text or data symbols from the \fIa.out\fP file.
1257This sometimes causes unexpected symbol names to be printed
1258with data (e.g. \fIsavr5+022\fP).
1259This does not happen if
1260\fB?\fR is used for text (instructions)
1261and \fB/\fP for data.
1262.IP 3.
1263ADB cannot handle C register variables
1264in the most recently activated function.
1265.LP
1266.NH
1267Acknowledgements
1268.PP
1269The authors are grateful for the thoughtful comments
1270on how to organize this document
1271from R. B. Brandt, E. N. Pinson and B. A. Tague.
1272D. M. Ritchie made the system changes necessary to accommodate
1273tracing within ADB. He also participated in discussions
1274during the writing of ADB.
1275His earlier work with DB and CDB led to many of the
1276features found in ADB.
1277.SG MH-8234-JFM/1273-SRB-unix
1278.NH
1279References
1280.LP
1281.IP 1.
1282D. M. Ritchie and K. Thompson,
1283``The UNIX Time-Sharing System,''
1284CACM, July, 1974.
1285.IP 2.
1286B. W. Kernighan and D. M. Ritchie,
1287.ul
1288The C Programming Language,
1289Prentice-Hall, 1978.
1290.IP 3.
1291K. Thompson and D. M. Ritchie,
1292UNIX Programmer's Manual - 7th Edition,
12931978.
1294.IP 4.
1295B. W. Kernighan and P. J. Plauger,
1296.ul
1297Software Tools,
1298Addison-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
1319Figure 1: C program with pointer bug
1320.LP
1321.P1
1322struct buf {
1323 int fildes;
1324 int nleft;
1325 char *nextp;
1326 char buff[512];
1327 }bb;
1328struct buf *obuf;
1329
1330char *charp "this is a sentence.";
1331
1332main(argc,argv)
1333int argc;
1334char **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\';
1348printf("debug 1 %s\\n",charp);
1349 while(cc= *charp++)
1350 putc(cc,obuf);
1351 fflush(obuf);
1352}
1353.P2
1354.sp 100
1355.SH
1356Figure 2: ADB output for C program of Figure 1
1357.LP
1358.P1
1359.ft B
1360adb 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
1374ps 0170010
1375pc 0204 ~main+0152
1376sp 0177740
1377r5 0177752
1378r4 01
1379r3 0
1380r2 0
1381r1 0
1382r0 0124
1383~main+0152: mov _obuf,(sp)
1384.ft B
1385$e
1386.ft R
1387savr5: 0
1388_obuf: 0
1389_charp: 0124
1390_errno: 0
1391_fout: 0
1392.ft B
1393$m
1394.ft R
1395text map \`ex1\'
1396b1 = 0 e1 = 02360 f1 = 020
1397b2 = 0 e2 = 02360 f2 = 020
1398data map \`core1\'
1399b1 = 0 e1 = 03500 f1 = 02000
1400b2 = 0175400 e2 = 0200000 f2 = 05500
1401.ft B
1402*charp/s
1403.ft R
14040124: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\1dL\ 3x\7f \ 3N\1dh\ 4@\1dx\7f&\10_
1405~
1406.ft B
1407charp/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
1415main.argc/d
1416.ft R
14170177756: 2
1418.ft B
1419*main.argv/3o
1420.ft R
14210177762: 0177770 0177776 0177777
1422.ft B
14230177770/s
1424.ft R
14250177770: a.out
1426.ft B
1427*main.argv/3o
1428.ft R
14290177762: 0177770 0177776 0177777
1430.ft B
1431*"/s
1432.ft R
14330177770: a.out
1434.ft B
1435 .=o
1436.ft R
1437 0177770
1438.ft B
1439 .\(mi10/d
1440.ft R
14410177756: 2
1442.ft B
1443$q
1444.P2
1445.sp 100
1446.SH
1447Figure 3: Multiple function C program for stack trace illustration
1448.LP
1449.P1
1450int fcnt,gcnt,hcnt;
1451h(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
1461g(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
1471f(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
1481main()
1482{
1483 f(1,1);
1484}
1485.P2
1486.sp 100
1487.SH
1488Figure 4: ADB output for C program of Figure 3
1489.LP
1490.P1
1491.ft B
1492adb
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
1506HIT DEL KEY
1507.ft R
1508adb
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
1537fcnt/d
1538.ft R
1539_fcnt: 1173
1540.ft B
1541gcnt/d
1542.ft R
1543_gcnt: 1173
1544.ft B
1545hcnt/d
1546.ft R
1547_hcnt: 1172
1548.ft B
1549h.x/d
1550.ft R
1551022004: 2346
1552.ft B
1553$q
1554.P2
1555.sp 100
1556.SH
1557Figure 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
1565char input[] "data";
1566char ibuf[518];
1567int tabs[MAXLINE];
1568.sp .5
1569main()
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 */
1601tabpos(col)
1602int 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 */
1611settab(tabp)
1612int *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
1622Figure 6a: ADB output for C program of Figure 5
1623.LP
1624.P1
1625.ft B
1626adb a.out \(mi
1627settab+4:b
1628fopen+4:b
1629getc+4:b
1630tabpos+4:b
1631$b
1632.ft R
1633breakpoints
1634count bkpt command
16351 ~tabpos+04
16361 _getc+04
16371 _fopen+04
16381 ~settab+04
1639.ft B
1640settab,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
1649settab,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
1659a.out: running
1660breakpoint ~settab+04: tst \(mi(sp)
1661.ft B
1662settab+4:d
1663:c
1664.ft R
1665a.out: running
1666breakpoint _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
1676tabs,3/8o
1677.ft R
167803500: 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
1684Figure 6b: ADB output for C program of Figure 5
1685.LP
1686.P1
1687.ft B
1688:c
1689.ft R
1690a.out: running
1691breakpoint _getc+04: mov 04(r5),r1
1692.ft B
1693ibuf+6/20c
1694.ft R
1695__cleanu+0202: This is a test of
1696.ft B
1697:c
1698.ft R
1699a.out: running
1700breakpoint ~tabpos+04: cmp $0120,04(r5)
1701.ft B
1702tabpos+4:d
1703settab+4:b settab,5?ia
1704settab+4:b settab,5?ia; 0
1705getc+4,3:b main.c?C; 0
1706settab+4:b settab,5?ia; ptab/o; 0
1707$b
1708.ft R
1709breakpoints
1710count bkpt command
17111 ~tabpos+04
17123 _getc+04 main.c?C;0
17131 _fopen+04
17141 ~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:
17210177766: 0177770
17220177744: @\`
1723T0177744: T
1724h0177744: h
1725i0177744: i
1726s0177744: s
1727.P2
1728.sp 100
1729.SH
1730Figure 7: ADB output for C program with breakpoints
1731.LP
1732.in +.5i
1733.nf
1734.ps 8
1735.vs 9
1736.ft B
1737adb ex3 \(mi
1738h+4:b hcnt/d; h.hi/; h.hr/
1739g+4:b gcnt/d; g.gi/; g.gr/
1740f+4:b fcnt/d; f.fi/; f.fr/
1741:r
1742.ft R
1743ex3: running
1744_fcnt: 0
17450177732: 214
1746symbol not found
1747.ft B
1748f+4:b fcnt/d; f.a/; f.b/; f.fi/
1749g+4:b gcnt/d; g.p/; g.q/; g.gi/
1750h+4:b hcnt/d; h.x/; h.y/; h.hi/
1751:c
1752.ft R
1753ex3: running
1754_fcnt: 0
17550177746: 1
17560177750: 1
17570177732: 214
1758_gcnt: 0
17590177726: 2
17600177730: 3
17610177712: 214
1762_hcnt: 0
17630177706: 2
17640177710: 1
17650177672: 214
1766_fcnt: 1
17670177666: 2
17680177670: 3
17690177652: 214
1770_gcnt: 1
17710177646: 5
17720177650: 8
17730177632: 214
1774.ft B
1775HIT DEL
1776f+4:b fcnt/d; f.a/"a = "d; f.b/"b = "d; f.fi/"fi = "d
1777g+4:b gcnt/d; g.p/"p = "d; g.q/"q = "d; g.gi/"gi = "d
1778h+4:b hcnt/d; h.x/"x = "d; h.y/"h = "d; h.hi/"hi = "d
1779:r
1780.ft R
1781ex3: running
1782_fcnt: 0
17830177746: a = 1
17840177750: b = 1
17850177732: fi = 214
1786_gcnt: 0
17870177726: p = 2
17880177730: q = 3
17890177712: gi = 214
1790_hcnt: 0
17910177706: x = 2
17920177710: y = 1
17930177672: hi = 214
1794_fcnt: 1
17950177666: a = 2
17960177670: b = 3
17970177652: fi = 214
1798.ft B
1799HIT DEL
1800$q
1801.in -.5i
1802.sp 100
1803.SH
1804Figure 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
1853407 files
1854.sp
1855.l1
1856a.out hdr text+data
1857.l2
1858| | |
1859.l3
1860 0 D
1861.sp
1862.l1
1863core hdr text+data stack
1864.l5
1865| | ......| |
1866.l6
1867 0 D S E
1868.sp 2
1869.ul
1870410 files (shared text)
1871.sp
1872.l1
1873a.out hdr text data
1874.l2
1875| | | |
1876.l3
1877 0 T B D
1878.sp
1879.la
1880core hdr data stack
1881.lb
1882| | ......| |
1883.lc
1884 B D S E
1885.sp 2
1886.ul
1887411 files (separated I and D space)
1888.sp
1889.l1
1890a.out hdr text data
1891.l2
1892| | | |
1893.l3
1894 0 T 0 D
1895.sp
1896.la
1897core hdr data stack
1898.lb
1899| | ......| |
1900.lc
1901 0 D S E
1902.sp 2
1903The following
1904.ul
1905adb
1906variables 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
1918Figure 9: ADB output for maps
1919.LP
1920.nf
1921.in +.5i
1922.ft B
1923adb map407 core407
1924$m
1925.ft R
1926text map \`map407\'
1927b1 = 0 e1 = 0256 f1 = 020
1928b2 = 0 e2 = 0256 f2 = 020
1929data map \`core407\'
1930b1 = 0 e1 = 0300 f1 = 02000
1931b2 = 0175400 e2 = 0200000 f2 = 02300
1932.ft B
1933$v
1934.ft R
1935variables
1936d = 0300
1937m = 0407
1938s = 02400
1939.ft B
1940$q
1941.sp 2
1942adb map410 core410
1943$m
1944.ft R
1945text map \`map410\'
1946b1 = 0 e1 = 0200 f1 = 020
1947b2 = 020000 e2 = 020116 f2 = 0220
1948data map \`core410\'
1949b1 = 020000 e1 = 020200 f1 = 02000
1950b2 = 0175400 e2 = 0200000 f2 = 02200
1951.ft B
1952$v
1953.ft R
1954variables
1955b = 020000
1956d = 0200
1957m = 0410
1958s = 02400
1959t = 0200
1960.ft B
1961$q
1962.sp 2
1963adb map411 core411
1964$m
1965.ft R
1966text map \`map411\'
1967b1 = 0 e1 = 0200 f1 = 020
1968b2 = 0 e2 = 0116 f2 = 0220
1969data map \`core411\'
1970b1 = 0 e1 = 0200 f1 = 02000
1971b2 = 0175400 e2 = 0200000 f2 = 02200
1972.ft B
1973$v
1974.ft R
1975variables
1976d = 0200
1977m = 0411
1978s = 02400
1979t = 0200
1980.ft B
1981$q
1982.in -.5i
1983.sp 100
1984.SH
1985Figure 10: Simple C program for illustrating formatting and patching
1986.LP
1987.P1
1988char str1[] "This is a character string";
1989int one 1;
1990int number 456;
1991long lnum 1234;
1992float fpt 1.25;
1993char str2[] "This is the second character string";
1994main()
1995{
1996 one = 2;
1997}
1998.P2
1999.sp 100
2000.SH
2001Figure 11: ADB output illustrating fancy formats
2002.LP
2003.nf
2004.ps 9
2005.vs 11p
2006.ft B
2007adb map410 core410
2008<b,\(mi1/8ona
2009.ft R
2010020000: 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
2021savr5+02: 0 0 0 0 0 0 0 0
2022.sp .5
2023.ft B
2024<b,20/4o4^8Cn
2025.ft R
2026020000: 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 @\`@\`@\`@\`@\`@\`@\`@\`
2039data address not found
2040.ft B
2041<b,20/4o4^8t8cna
2042.ft R
2043020000: 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
2054savr5+02: 0 0 0 0
2055savr5+012: 0 0 0 0
2056data address not found
2057.ft B
2058<b,10/2b8t^2cn
2059.ft R
2060020000: 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
2075Figure 12: Directory and inode dumps
2076.LP
2077.nf
2078.ft B
2079adb dir \(mi
2080=nt"Inode"t"Name"
20810,\(mi1?ut14cn
2082.ft R
2083
2084 Inode Name
20850: 652 .
2086 82 ..
2087 5971 cap.c
2088 5323 cap
2089 0 pp
2090.sp 4
2091.ft B
2092adb /dev/src \(mi
2093.ft B
209402000>b
2095?m<b
2096.ft R
2097new map \`/dev/src\'
2098b1 = 02000 e1 = 0100000000 f1 = 0
2099b2 = 0 e2 = 0 f2 = 0
2100.ft B
2101$v
2102.ft R
2103variables
2104b = 02000
2105.ft B
2106<b,\(mi1?"flags"8ton"links,uid,gid"8t3bn"size"8tbrdn"addr"8t8un"times"8t2Y2na
2107.ft R
210802000: 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
211402040: 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
212002100: 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
2129ADB Summary
2130.LP
2131.LP
2132.if t .2C
2133.nr VS 9
2134.nr VS 11
2135.SH
2136Command Summary
2137.LP
2138.ta .7i
2139a) formatted printing
2140.sp .5
2141.IP "\fB? \fIformat\fR" .7i
2142print from \fIa.out\fR file according to \fIformat\fR
2143.IP "\fB/ \fIformat\fR" .7i
2144print from \fIcore\fR file according to \fIformat\fR
2145.IP "\fB= \fIformat\fR" .7i
2146print the value of \fIdot\fR
2147.sp .5
2148.IP "\fB?w\fR expr" .7i
2149write expression into \fIa.out\fR file
2150.IP "\fB/w\fR expr" .7i
2151write expression into \fIcore\fR file
2152.sp .5
2153.IP "\fB?l\fR expr" .7i
2154locate expression in \fIa.out\fR file
2155.LP
2156.ta .7i
2157b) 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
2170c) 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
2186d) 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
2193e) 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
2200Format 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
2223Expression Summary
2224.LP
2225.ta .7i
2226a) 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
2239b) 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
2252c) 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