figure 1: Little languages in unix, early 1980s.

figure 2: oDt- 8 debugger syntax, circa 1967.

Debuggers
adb
dbx
stabs

Programming tools
lex
make
m4
ratfor
yacc

Shells/utilities
sh
csh
awk
bc, dc
ed, ex, vi
sed

Games

rogue, trek

text formatting
eqn
pic
nroff, troff

Libraries

regex

configuration

sendmail.cf

400 /

display the content of memory location 400

400 / 6046

observe the value is 6046 at that location

400 / 6046 2345

rewrite the value to 2345

3000B

set a breakpoint at 3000

ODT- 8 Octal Debugging Technique Manual, DEC-D8-CoCo-D, Dec. 1967

figure 3: unix V3 “db” syntax, circa 1971

ous forms in active use, as shown in Figure 1.

These languages vary from complete programming languages (sh) to preprocessors (yacc) to command-line syntax (adb) to representations of state machines or data structures (regular expressions, debugger “stabs”). Twenty years later, when Sun Microsystems released the modern Unix system Solaris 10, almost all of the new significant operating-system features involved the introduction of new purpose-built languages: the DTrace debugging software introduced the D language for tracing queries; the Fault Management system included a language for describing fault propagations; the Zones and Service Management features included XML configuration grammars and new command-line interpreters.

The history of one of these little Unix languages, that of the adb debugger, is particularly illustrative of the accidental evolution and stickiness of something small but useful in a larger system.

 

evolution trumps intelligent Design The early development of Unix occurred on DEC PDP systems, which had a very simple debugger available known as ODT, or Octal Debugging Technique. (This terrific name conjures thoughts of a secret kung fu maneuver used to render the PDP’s 12-bit registers paralyzed.) The ODT program supported an incredibly

primitive syntax: an octal physical memory address was specified at the start of each command and suffixed with a single character (say, B for breakpoint) or a slash (/) to read and optionally to write the content of that memory location, as shown in Figure 2.

Thus, a little language was born. The ODT syntax clearly inspired the form of the first debugger for the new Unix system being developed on the PDP, which was simply called db. At the time of Unix v3 in 1971, the db command syntax borrowed the basic ODT model and began extending it with additional character suffixes to define addressing modes and formatting options, as shown in Figure 3.

By 1980, db had been replaced by adb, which was included with the AT&T SVR3 Unix distribution. The syntax had evolved to add new debugging commands over the intervening years and now supported not just simple addresses but arithmetic expressions (123+456 / was now legal). Also, a character after “/” now indicated a data format, and a character after “$” or “:” now indicated an action. The adb syntax is shown in Figure 4.

The addition of “$<” to read an external file of commands was particularly interesting, because it spawned the development of primitive adb programs or macros that executed a series of commands to display the contents of a C data structure at a particular memory address. That is, to display a kernel proc structure, you

address / Print a word in octal address \ Print a byte in octal address ` Print a byte in ASCii address Disassemble an instruction Print the machine registers

Unix Version 3 Manual Pages, DB( 1), nov. 3, 1971.

figure 4: At&t SVR3 “adb” syntax, circa 1980.

expression /o

Print a two-byte integer in octal at the specified address

expression /x

Print a two-byte integer in hexadecimal at the specified address

expression /d

Print a two-byte integer in decimal at the specified address

$a Print an Algol stack backtrace $c Print a C stack backtrace $r Print the machine registers

expression :b

Set a breakpoint

$< filename read and execute the
command found in
the specified file

Kernighan, B. ratfor: A preprocessor for a rational Fortran. Soft ware—Practice and Experience. oct. 1975.

 

would take its address and then type “$<proc” to execute a predefined series of commands to display each memory of the C data structure for a process. The content of the proc macro in SunOS 4 from 1984 is shown in Figure 5. To make this output understandable, the “/” command could now be suffixed with quoted string labels, newlines (n) and tabs (16t) to be included among the decoded data.

38 communicAtionS of the Acm | APriL 2009 | voL. 52 | no. 4

References:

Archives