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()