COHERENT manpages
This page displays the COHERENT manpage for db [Assembler-level symbolic debugger].
List of available manpages
Index
db -- Command
Assembler-level symbolic debugger
db [-a symfile] [-cdefort] [[mapfile] program]
db is an interactive, symbolic debugger. It allows you to run object files
and executable programs under trace control (see the Lexicon entry for
ptrace), run programs with embedded breakpoints, and dump and patch files
in a variety of forms. You can use it to debug assembly-language programs
that have been assembled by as, the Mark Williams assembler, and programs
that have been compiled with the Mark Williams C compiler cc.
What is db?
db is a symbolic debugger, which means that it works with the symbol tables
that the compiler builds into the object files it generates. Because db
works on the level of assembly language, you need a working knowledge of
i80386 assembly language and microprocessor architecture.
Invoking db
To invoke db, type its name, plus the options you want (if any) and the
name of the files with which you will be working. mapfile is an object
file that supplies a symbol table. program is the executable program to be
debugged. If both names are given, the options default to -c. If only one
name is given, it is the program; in this case the options default to -o.
If both names are omitted, mapfile defaults to l.out or a.out, and program
defaults to core. If possible, db accesses program with write permission.
db recognizes the following command-line options:
-a symfile
Read symfile for the list of symbols within the executable, instead of
the executable's symbol table. This lets you copy an executable's
symbol table in symfile, then strip that executable.
-c program is a core file produced by a user core dump. db checks the name
of the command that invoked the process that produced the core, against
the name of the mapfile, if given. Pure segments are read from the
mapfile.
-d program is a system dump. If the command line names no files, mapfile
defaults to /COHERENT and program defaults to /dev/dump.
-e The next argument is an object file; db executes it as a child process
and passes it the rest of the command line. This permits the shell to
expand wildcard characters that you place in the db command line,
without spoiling the syntax of the db command.
-f Map program as a straight array of bytes (file).
-k Map program as a kernel process; mapfile defaults to /coherent, and
program defaults to /dev/kmem.
-o program is an object file. If mapfile is given, it is another object
file that provides the symbol table.
-p prompt
Change the command prompt from db: to prompt.
-r Only read the file, even if you have write permission for it. Use this
to give a file additional protection.
-s Do not load symbol table.
-t Perform input and output for db via /dev/tty. This permits you to debug
a process whose standard input or output has been redirected.
Commands and Addresses
db executes commands that you give it from the standard input. db displays
the prompt
db:
when it is ready to receive a command. To change its prompt, use the -p
option, described above. A command usually consists of an address, which
tells db where in the program to execute the command; and then the command
name and its options, if any.
An address is represented by an expression, which can be built out of one
or more of the following elements:
-> The `.', which represents the current address. When you enter an
address, db sets the current address to that location. To advance the
current address, type the <Enter> key.
-> The name of a register. db recognizes the names of all registers on the
80386 microprocessor and the 80387 numeric co-processor. You can
preceed a register name with a `%', but this is not required. If your
program contains function eax(), the identifier eax identifies the
function and %eax the register. If your program does not define eax,
then either eax or %eax means the register. For example, the commands
sin:b
:e
:s
%st0?N
sets a breakpoint at routine sin(), executes to it, single steps into
it, and then prints the contents of the NDP stacktop %st0, which one
step into sin() contains the argument.
Typing the name of a register displays its contents. db displays
register contents and stack traceback in hexadecimal values, regardless
of the current default radix.
-> The symbols d, i, and u, which represent location 0 in, respectively,
the data space, the instruction space, and the u-area.
-> The names of global symbols and symbolic addresses can be used in place
of the addresses where they occur. This is useful when setting a
breakpoint at the beginning of a subroutine.
-> An integer constant, which can be used in the same manner as a global
symbol. The default is hexadecimal; a leading 0 indicates octal and 0x
indicates hexadecimal.
-> You can use the following binary operators:
+ Addition
- Subtraction
* Multiplication
/ Integer division
All arithmetic is done in longs.
-> You can use the following unary operators:
~ Complementation
- Negation
* Indirection
All operators are supported with their normal level of precedence. You
can use parentheses `()' for binding.
Every symbol refers to a segment: the data segment, the instruction
segment, or the u-area. This segment, in turn, dictates the format in
which db displays by default what it finds at that address. The format
used by an expression is that of its leftmost operand. The symbols d, i,
and u name specific segments in the absence of other symbols.
Displaying Information
To display information about program, use an expression of the form
[address][,count]?[format]
This displays format for count iterations, starting at address. The symbol
`.' represents the address, which defaults to the current display address
if omitted. count defaults to one. The format string consists of one or
more of the following characters:
^ Reset display address to `.'
+ Increment display address
- Decrement display address
b Byte
c char; control and non-chars escaped
C Like `c' except `\0' not displayed
d Decimal
f float
F double
i Machine instruction, disassembled
l long
n Output `\n'
N NDP (80387) register
O octal
p Symbolic address
s String terminated by `\0', with escapes
S String terminated by `\0', no escapes
u unsigned
w word
x Hexadecimal
Y time (as in i-node, etc.)
The format characters d, o, u, and x, specify a numeric base. Each of
these can be followed by b, l, or w, which specify a datum size, to
describe a single datum for display. A format item may also be preceded by
a count that specifies how many times the item is to be applied. format
defaults to the previously set format for the segment (initially o for data
and u-area, and i for instructions). Except where otherwise noted, db
increments the display address by the size of the datum displayed after
each format item.
Execution Commands
In the following commands, address defaults to the address where execution
stopped, unless otherwise specified; count and expr default to one.
commands is an arbitrary string of db commands, terminated by a newline. A
newline may be included by preceding it with a backslash `\'.
[address]=
Print address (offset) in hexadecimal. address defaults to `.'.
[address]=value[,value[,value]...]
Patch value into the program, beginning at point address. The address
defaults to `.'. You can list up to ten values. The command = assigns
values to sequential locations in the traced process. db determines
the size of the assigned value from the last display format used. You
can set and display the registers of the traced process, just like any
other address in the traced process.
? Print the last error message.
[address][,n]?[ft]
Display formatted information. ft indicates the format, which must be
one of bcCdfFilnNopsSuvwxY. For details, see the command :hf, below
address?
Print address.
!command
Pass command to a shell for execution.
[address] :a
Print address symbolically. address defaults to `.'.
[address]:b[commands]
Set a breakpoint at address. Execute commands when the breakpoint is
encountered. commands defaults to i+.:a\ni+.?i\n:x\n -- that is,
print the breakpoint address, disassemble the instruction at the
breakpoint address, and read more commands from the console.
:br [commands]
Set breakpoint at return from current routine, and execute commands.
The default commands are the same as for :b, above.
[address] :c
Continue execution from address.
[address] :d[r][s]
Delete the breakpoint previously set at address. If the optional r or
s is specified, delete return or single-step breakpoint. address
defaults to `.'.
[address]:e[commandline]
Begin traced execution of the object file at address (default, entry
point). db parses commandline and passes it to the traced process.
argv[0] must be typed directly after :e if supplied. For example,
:eprogname foo bar baz
sets argv[0] to progname, argv[1] to foo, argv[2] to bar, and argv[3]
to baz. Quotation marks, apostrophes, and redirection are parsed as by
the shell, but special characters `?*[]' and shell punctuation
`(){}|;' are not. For complete shell command line parsing use the -e
option, above.
Note that you must use the :e command to start the program execution
prior to using the single-step, trace-back, or display-register
commands. For example, the following COHERENT command sequence sets a
breakpoint at main(), begins execution, and single-steps ten times
through the program after having reached the breakpoint:
main:b
:e
,10:s
:f Print type of fault that caused a core dump or stopped the traced
process.
:h Print help information.
:hf Print help information about display formats. db recognizes the
following display formats:
b Byte.
c char; control, and non-chars printed as escape sequences.
C char; control and non-chars print as `.'.
d Decimal.
f float.
F double.
i Disassembled machine instruction.
l long.
n Output `\n'.
N NDP (80387) floating-point register (ten bytes).
o Octal.
p Symbolic address.
s String (NUL-terminated) with escape sequences.
S String (NUL-terminated).
u unsigned.
v File system l3-block address (three bytes).
w Word.
x Hexadecimal.
Y Time.
Options d, o, u, and x specify numeric bases (decimal, octal, unsigned
decimal, hexadecimal). Each may be followed by b, w, or l to indicate
a datum size (respectively, byte, word, or long).
:m Display segmentation map.
:p Display all breakpoints.
[expr] :q
If expr is nonzero, quit the current level of command input (see :x).
expr defaults to one. End-of-file is equivalent to :q.
:r Display the contents of all registers on the microprocessor.
:rN Display the contents of all registers on the microprocessor and on the
numeric co-processor. If your system does not possess a numeric co-
processor, it displays the contents of the pseudo-registers used by
COHERENT's emulator.
[address][,count]:s[c][commands]
Single-step execution starting at address, for count steps, executing
commands at each step. commands defaults to i+.?i.
After a single-step command, <Enter> is equivalent to .,1:s[c].
The option c tells db to turn off single-stepping at a subroutine call
and turn it on again upon return.
[depth] :t
Print a call traceback to depth levels. If depth is zero (default),
unwind the whole stack.
[expr] :x
If expr is nonzero, read and execute commands from the standard input
up to end of file or to receiving the command :q. expr defaults to
one.
Note that the :c, :s, :t, and :r commands cannot be executed before a
program is started. If you are debugging the program hello, do the
following first:
db hello
main:b
:e
This invokes the debugger for hello and advances it to main. Now you can
use the full set of commands.
Examples
The first example uses db to examine a program named myprog, which has
core-dumped. To debug it, use the command
db myprog core
You could then issue the following commands to see where the problem lay:
:f This command displays the fault that caused the core dump.
:r This displays the contents of registers at the point where the program
core dumped.
:t This command traces back the stack. With this command, you can see how
your program arrived at the point where it core dumped. You can use
this to find the point in your code where the program ``jumps the
rails''; often, this is all the information you need to fix the fault.
i1?
This prints the value of global variable i1 in your program at the time
of the core dump.
:q Quit db. At this point, you should have a good idea of what went wrong
with your program.
For another example, consider the following program, named segv.c:
main()
{
register char *cp;
cp = &main;
*cp = 1000;
}
Compile this program with the command cc segv.c. To run it, type segv; as
you can see, it crashes with a segmentation violation, producing a core-
dump file named core. Now, you can use db to find out why the program core
dumped.
To invoke the debugger, type:
db segv core
Now, type the db command:
:f
This tells db to print the type of fault that caused the program to dump
core. db replies:
segmentation violation
Now, type:
*%eip?
db replies:
000000E9 movb (%ebx), $0xE8
Here, db gives you the value of the instruction pointer register %eip when
the segmentation violation occurred and disassembles the instruction at
that location. The offending instruction is trying to store indirectly
through register %ebx. Type:
:t
db prints a traceback of the call stack:
7FFFFD24 000000E9 main(1, 0x7FFFFD38, 0x7FFFFD40)
This shows the program was in main() and not in any other function. Type:
:r
db prints contents of the machine registers:
%cs =000B %eip=000000E9 %ss =0013 %fw =00011246
%ds =0013 %es =0013 %fs =0000 %gs =0000
%eax=00000001 %ebx=000000D4 %ecx=00000013 %edx=7FFFFD40
%esp=7FFFFD1C %ebp=7FFFFD24 %edi=004090F4 %esi=00400D24
This shows that register %ebx has the value 0xD4 at the time of the core
dump. Print the contents of %ebx symbolically:
%ebx?p
db replies:
00000020 main
The program is trying to store into the address of main. This causes a
segmentation violation because COHERENT does not allow programs to write on
code. Finally, type
:q
to exit from db.
In the last example, suppose you want to print the current address, the
instruction at the current address, and the contents of global variable j
when you hit function fn while running db. Type:
db cmd
main:b
:e
fn:b.:a\
.?i\
j?\
:x
The backslash `\' at the end of a line ``escapes'' a newline -- that is, it
tells db to ignore the newline, and concatenate the contents of the next
line onto those of the present line. Thus, the fn command line (four
physical lines with escaped newlines) forms a single db command that says
the following:
.:a
Print the current position as an address.
.?i
Print the contents of the current position as an instruction.
j? print the contents of j.
:x Read more db input from the console.
The :x is necessary if you want to keep debugging interactively after db
executes the breakpoint command list!
See Also
commands,
coff.h,
core,
l.out.h,
od,
ptrace()






