9.  References

1.
D. M. Ritchie and K. Thompson, ``The UNIX Time-Sharing System,'' CACM, July, 1974.
2.
B. W. Kernighan and D. M. Ritchie, The C Programming Language, Prentice-Hall, 1978.
3.
K. Thompson and D. M. Ritchie, UNIX Programmer's Manual - 7th Edition, 1978.
4.
B. W. Kernighan and P. J. Plauger, Software Tools, Addison-Wesley, 1976.

Figure 1: C program with pointer bug


struct buf {
int fildes;
int nleft;
char *nextp;
char buff[512];
}bb;
struct buf *obuf;

char *charp "this is a sentence.";

main(argc,argv)
int argc;
char **argv;
{
char cc;

if(argc < 2) {
printf("Input file missing\n");
exit(8);
}

if((fcreat(argv[1],obuf)) < 0){
printf("%s : not found\n", argv[1]);
exit(8);
}
charp = 'T';
printf("debug 1 %s\n",charp);
while(cc= *charp++)
putc(cc,obuf);
fflush(obuf);
}

Figure 2: ADB output for C program of Figure 1


adb a.out core
$c
~main(02,0177762)
$C
~main(02,0177762)
argc: 02
argv: 0177762
cc: 02124
$r
ps 0170010
pc 0204 ~main+0152
sp 0177740
r5 0177752
r4 01
r3 0
r2 0
r1 0
r0 0124
~main+0152: mov _obuf,(sp)
$e
savr5: 0
_obuf: 0
_charp: 0124
_errno: 0
_fout: 0
$m
text map `ex1'
b1 = 0 e1 = 02360 f1 = 020
b2 = 0 e2 = 02360 f2 = 020
data map `core1'
b1 = 0 e1 = 03500 f1 = 02000
b2 = 0175400 e2 = 0200000 f2 = 05500
*charp/s
0124: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTLx Nh@x&_
~
charp/s
_charp: T

_charp+02: this is a sentence.

_charp+026: Input file missing
main.argc/d
0177756: 2
*main.argv/3o
0177762: 0177770 0177776 0177777
0177770/s
0177770: a.out
*main.argv/3o
0177762: 0177770 0177776 0177777
*"/s
0177770: a.out
.=o
0177770
.-10/d
0177756: 2
$q

Figure 3: Multiple function C program for stack trace illustration


int fcnt,gcnt,hcnt;
h(x,y)
{
int hi; register int hr;
hi = x+1;
hr = x-y+1;
hcnt++ ;
hj:
f(hr,hi);
}

g(p,q)
{
int gi; register int gr;
gi = q-p;
gr = q-p+1;
gcnt++ ;
gj:
h(gr,gi);
}

f(a,b)
{
int fi; register int fr;
fi = a+2*b;
fr = a+b;
fcnt++ ;
fj:
g(fr,fi);
}

main()
{
f(1,1);
}

Figure 4: ADB output for C program of Figure 3


adb
$c
~h(04452,04451)
~g(04453,011124)
~f(02,04451)
~h(04450,04447)
~g(04451,011120)
~f(02,04447)
~h(04446,04445)
~g(04447,011114)
~f(02,04445)
~h(04444,04443)
HIT DEL KEY
adb
,5$C
~h(04452,04451)
x: 04452
y: 04451
hi: ?
~g(04453,011124)
p: 04453
q: 011124
gi: 04451
gr: ?
~f(02,04451)
a: 02
b: 04451
fi: 011124
fr: 04453
~h(04450,04447)
x: 04450
y: 04447
hi: 04451
hr: 02
~g(04451,011120)
p: 04451
q: 011120
gi: 04447
gr: 04450
fcnt/d
_fcnt: 1173
gcnt/d
_gcnt: 1173
hcnt/d
_hcnt: 1172
h.x/d
022004: 2346
$q

Figure 5: C program to decode tabs


#define MAXLINE 80
#define YES 1
#define NO 0
#define TABSP 8
char input[] "data";
char ibuf[518];
int tabs[MAXLINE];
main()
{
int col, *ptab;
char c;
ptab = tabs;
settab(ptab); /*Set initial tab stops */
col = 1;
if(fopen(input,ibuf) < 0) {
printf("%s : not found\n",input);
exit(8);
}
while((c = getc(ibuf)) != -1) {
switch(c) {
case '\t': /* TAB */
while(tabpos(col) != YES) {
putchar(' '); /* put BLANK */
col++ ;
}
break;
case '\n': /*NEWLINE */
putchar('\n');
col = 1;
break;
default:
putchar(c);
col++ ;
}
}
}
/* Tabpos return YES if col is a tab stop */
tabpos(col)
int col;
{
if(col > MAXLINE)
return(YES);
else
return(tabs[col]);
}
/* Settab - Set initial tab stops */
settab(tabp)
int *tabp;
{
int i;
for(i = 0; i<= MAXLINE; i++)
(i%TABSP) ? (tabs[i] = NO) : (tabs[i] = YES);
}

Figure 6a: ADB output for C program of Figure 5


adb a.out -
settab+4:b
fopen+4:b
getc+4:b
tabpos+4:b
$b
breakpoints
count bkpt command
1 ~tabpos+04
1 _getc+04
1 _fopen+04
1 ~settab+04
settab,5?ia
~settab: jsr r5,csv
~settab+04: tst -(sp)
~settab+06: clr 0177770(r5)
~settab+012: cmp $0120,0177770(r5)
~settab+020: blt ~settab+076
~settab+022:
settab,5?i
~settab: jsr r5,csv
tst -(sp)
clr 0177770(r5)
cmp $0120,0177770(r5)
blt ~settab+076
:r
a.out: running
breakpoint ~settab+04: tst -(sp)
settab+4:d
:c
a.out: running
breakpoint _fopen+04: mov 04(r5),nulstr+012
$C
_fopen(02302,02472)
~main(01,0177770)
col: 01
c: 0
ptab: 03500
tabs,3/8o
03500: 01 0 0 0 0 0 0 0
01 0 0 0 0 0 0 0
01 0 0 0 0 0 0 0

Figure 6b: ADB output for C program of Figure 5


:c
a.out: running
breakpoint _getc+04: mov 04(r5),r1
ibuf+6/20c
__cleanu+0202: This is a test of
:c
a.out: running
breakpoint ~tabpos+04: cmp $0120,04(r5)
tabpos+4:d
settab+4:b settab,5?ia
settab+4:b settab,5?ia; 0
getc+4,3:b main.c?C; 0
settab+4:b settab,5?ia; ptab/o; 0
$b
breakpoints
count bkpt command
1 ~tabpos+04
3 _getc+04 main.c?C;0
1 _fopen+04
1 ~settab+04 settab,5?ia;ptab?o;0
~settab: jsr r5,csv
~settab+04: bpt
~settab+06: clr 0177770(r5)
~settab+012: cmp $0120,0177770(r5)
~settab+020: blt ~settab+076
~settab+022:
0177766: 0177770
0177744: @`
T0177744: T
h0177744: h
i0177744: i
s0177744: s

Figure 7: ADB output for C program with breakpoints

adb ex3 -
h+4:b hcnt/d; h.hi/; h.hr/
g+4:b gcnt/d; g.gi/; g.gr/
f+4:b fcnt/d; f.fi/; f.fr/
:r
ex3: running
_fcnt: 0
0177732: 214
symbol not found
f+4:b fcnt/d; f.a/; f.b/; f.fi/
g+4:b gcnt/d; g.p/; g.q/; g.gi/
h+4:b hcnt/d; h.x/; h.y/; h.hi/
:c
ex3: running
_fcnt: 0
0177746: 1
0177750: 1
0177732: 214
_gcnt: 0
0177726: 2
0177730: 3
0177712: 214
_hcnt: 0
0177706: 2
0177710: 1
0177672: 214
_fcnt: 1
0177666: 2
0177670: 3
0177652: 214
_gcnt: 1
0177646: 5
0177650: 8
0177632: 214
HIT DEL
f+4:b fcnt/d; f.a/"a = "d; f.b/"b = "d; f.fi/"fi = "d
g+4:b gcnt/d; g.p/"p = "d; g.q/"q = "d; g.gi/"gi = "d
h+4:b hcnt/d; h.x/"x = "d; h.y/"h = "d; h.hi/"hi = "d
:r
ex3: running
_fcnt: 0
0177746: a = 1
0177750: b = 1
0177732: fi = 214
_gcnt: 0
0177726: p = 2
0177730: q = 3
0177712: gi = 214
_hcnt: 0
0177706: x = 2
0177710: y = 1
0177672: hi = 214
_fcnt: 1
0177666: a = 2
0177670: b = 3
0177652: fi = 214
HIT DEL
$q

Figure 8: ADB address maps

407 files

a.out hdr text+data
                    | | | 0 D

core hdr text+data stack
                    | | ......| |
                    0 D S E

410 files (shared text)

a.out hdr text data
                    | | | | 0 T B D

core hdr data stack
                    | | ......| |
                    B D S E

411 files (separated I and D space)

a.out hdr text data
                    | | | | 0 T 0 D

core hdr data stack
                    | | ......| |
                    0 D S E

The following adb variables are set.
407 410 411

b base of data 0 B 0
d length of data D D-B D
s length of stack S S S
t length of text 0 T T

Figure 9: ADB output for maps

adb map407 core407
$m
text map `map407'
b1 = 0 e1 = 0256 f1 = 020
b2 = 0 e2 = 0256 f2 = 020
data map `core407'
b1 = 0 e1 = 0300 f1 = 02000
b2 = 0175400 e2 = 0200000 f2 = 02300
$v
variables
d = 0300
m = 0407
s = 02400
$q

adb map410 core410
$m
text map `map410'
b1 = 0 e1 = 0200 f1 = 020
b2 = 020000 e2 = 020116 f2 = 0220
data map `core410'
b1 = 020000 e1 = 020200 f1 = 02000
b2 = 0175400 e2 = 0200000 f2 = 02200
$v
variables
b = 020000
d = 0200
m = 0410
s = 02400
t = 0200
$q

adb map411 core411
$m
text map `map411'
b1 = 0 e1 = 0200 f1 = 020
b2 = 0 e2 = 0116 f2 = 0220
data map `core411'
b1 = 0 e1 = 0200 f1 = 02000
b2 = 0175400 e2 = 0200000 f2 = 02200
$v
variables
d = 0200
m = 0411
s = 02400
t = 0200
$q

Figure 10: Simple C program for illustrating formatting and patching


char str1[] "This is a character string";
int one 1;
int number 456;
long lnum 1234;
float fpt 1.25;
char str2[] "This is the second character string";
main()
{
one = 2;
}

Figure 11: ADB output illustrating fancy formats

adb map410 core410
<b,-1/8ona
020000: 0 064124 071551 064440 020163 020141 064143 071141
_str1+016: 061541 062564 020162 072163 064562 063556 0 02
_number:
_number: 0710 0 02322 040240 0 064124 071551 064440
_str2+06: 020163 064164 020145 062563 067543 062156 061440 060550
_str2+026: 060562 072143 071145 071440 071164 067151 0147 0
savr5+02: 0 0 0 0 0 0 0 0
<b,20/4o4^8Cn
020000: 0 064124 071551 064440 @`@`This i
020163 020141 064143 071141 s a char
061541 062564 020162 072163 acter st
064562 063556 0 02 ring@`@`@b@`
_number: 0710 0 02322 040240 H@a@`@`R@d @@
0 064124 071551 064440 @`@`This i
020163 064164 020145 062563 s the se
067543 062156 061440 060550 cond cha
060562 072143 071145 071440 racter s
071164 067151 0147 0 tring@`@`@`
0 0 0 0 @`@`@`@`@`@`@`@`
0 0 0 0 @`@`@`@`@`@`@`@`
data address not found
<b,20/4o4^8t8cna
020000: 0 064124 071551 064440 This i
_str1+06: 020163 020141 064143 071141 s a char
_str1+016: 061541 062564 020162 072163 acter st
_str1+026: 064562 063556 0 02 ring
_number:
_number: 0710 0 02322 040240 HR
_fpt+02: 0 064124 071551 064440 This i
_str2+06: 020163 064164 020145 062563 s the se
_str2+016: 067543 062156 061440 060550 cond cha
_str2+026: 060562 072143 071145 071440 racter s
_str2+036: 071164 067151 0147 0 tring
savr5+02: 0 0 0 0
savr5+012: 0 0 0 0
data address not found
<b,10/2b8t^2cn
020000: 0 0
_str1: 0124 0150 Th
0151 0163 is
040 0151 i
0163 040 s
0141 040 a
0143 0150 ch
0141 0162 ar
0141 0143 ac
0164 0145 te
$Q

Figure 12: Directory and inode dumps

adb dir -
=nt"Inode"t"Name"
0,-1?ut14cn

Inode Name
0: 652 .
82 ..
5971 cap.c
5323 cap
0 pp

adb /dev/src -
02000>b
?m<b
new map `/dev/src'
b1 = 02000 e1 = 0100000000 f1 = 0
b2 = 0 e2 = 0 f2 = 0
$v
variables
b = 02000
<b,-1?"flags"8ton"links,uid,gid"8t3bn"size"8tbrdn"addr"8t8un"times"8t2Y2na
02000: flags 073145
links,uid,gid 0163 0164 0141
size 0162 10356
addr 28770 8236 25956 27766 25455 8236 25956 25206
times 1976 Feb 5 08:34:56 1975 Dec 28 10:55:15

02040: flags 024555
links,uid,gid 012 0163 0164
size 0162 25461
addr 8308 30050 8294 25130 15216 26890 29806 10784
times 1976 Aug 17 12:16:51 1976 Aug 17 12:16:51

02100: flags 05173
links,uid,gid 011 0162 0145
size 0147 29545
addr 25972 8306 28265 8308 25642 15216 2314 25970
times 1977 Apr 2 08:58:01 1977 Feb 5 10:21:44

ADB Summary


Command Summary

a) formatted printing

? format
print from a.out file according to format
/ format
print from core file according to format
= format
print the value of dot
?w expr
write expression into a.out file
/w expr
write expression into core file
?l expr
locate expression in a.out file

b) breakpoint and program control

:b set breakpoint at dot
:c continue running program
:d delete breakpoint
:k kill the program being debugged
:r run a.out file under ADB control
:s single step

c) miscellaneous printing

$b print current breakpoints
$c C stack trace
$e external variables
$f floating registers
$m print ADB segment maps
$q exit from ADB
$r general registers
$s set offset for symbol match
$v print ADB variables
$w set output line width

d) calling the shell

! call shell to read rest of line

e) assignment to variables

>name assign dot to variable or register name

Format Summary

a the value of dot
b one byte in octal
c one byte as a character
d one word in decimal
f two words in floating point
i PDP 11 instruction
o one word in octal
n print a newline
r print a blank space
s a null terminated character string
nt move to next n space tab
u one word as unsigned integer
x hexadecimal
Y date
^ backup dot
"..." print string

Expression Summary

a) expression components

decimal integer e.g. 256
octal integer e.g. 0277
hexadecimal e.g. #ff
symbols e.g. flag _main main.argc
variables e.g. <b
registers e.g. <pc <r0
(expression) expression grouping

b) dyadic operators

+ add
- subtract
* multiply
% integer division
& bitwise and
| bitwise or
# round up to the next multiple

c) monadic operators

~ not
* contents of location
- integer negate