C H A P T E R 17 |
Debugging at the Machine-Instruction Level |
This chapter describes how to use event management and process control commands at the machine-instruction level, how to display the contents of memory at specified addresses, and how to display source lines along with their corresponding machine instructions. The next, step, stop and trace commands each support a machine-instruction level variant: nexti, stepi, stopi, and tracei. Use the regs command to print out the contents of machine registers or the print command to print out individual registers.
This chapter is organized into the following sections:
Using addresses and the examine or x command, you can examine the content of memory locations as well as print the assembly language instruction at each address. Using a command derived from adb(1), the assembly language debugger, you can query for:
You can print the assembly commands using the dis and listi commands. (See Using the dis Command and Using the listi Command.)
Use the examine command, or its alias x, to display memory contents or addresses.
Use the following syntax to display the contents of memory starting at address for count items in format format. The default address is the next one after the last address previously displayed. The default count is 1. The default format is the same as was used in the previous examine command, or X if this is the first command given.
The syntax for the examine command is:
examine [address] [/ [count] [format]] |
To display the contents of memory from address1 through address2 inclusive, in format format, type:
examine address1, address2 [/ [format]] |
Display the address, instead of the contents of the address in the given format by typing:
examine address = [format] |
To print the value stored at the next address after the one last displayed by examine, type:
examine +/ i |
To print the value of an expression, enter the expression as an address:
examine address=format examine address= |
The address is any expression resulting in or usable as an address. The address may be replaced with a + (plus sign), which displays the contents of the next address in the default format.
For example, the following are valid addresses.:
Symbolic addresses used to display memory are specified by preceding a name with an ampersand (&). Function names can be used without the ampersand; &main is equal to main. Registers are denoted by preceding a name with a dollar sign ($).
The format is the address display format in which dbx displays the results of a query. The output produced depends on the current display format. To change the display format, supply a different format code.
The default format set at the start of each dbx session is X, which displays an address or value as a 32-bit word in hexadecimal. The following memory display formats are legal.
Display as 32 bits (4 bytes) in hexadecimal. (default format) |
|
Display as a string of characters terminated by a null byte. |
|
The count is a repetition count in decimal. The increment size depends on the memory display format.
The following examples show how to use an address with count and format options to display five successive disassembled instructions starting from the current stopping point.
The dis command is equivalent to the examine command with i as the default display format.
Here is the syntax for the dis command.
dis [address] [address1, address2] [/count] |
To display source lines with their corresponding assembly instructions, use the listi command, which is equivalent to the command list -i. See the discussion of list -i in Printing a Source Listing.
Machine-instruction level commands behave the same as their source level counterparts except that they operate at the level of single instructions instead of source lines.
To single step from one machine instruction to the next machine instruction, use the nexti command or the stepi command
The nexti command and the stepi command behave the same as their source-code level counterparts: the nexti command steps over functions, the stepi command steps into a function called by the next instruction (stopping at the first instruction in the called function). The command forms are also the same. See next Command and step Command for a description.
The output from the nexti command and the stepi command differs from the corresponding source level commands in two ways:
(dbx) func hand::ungrasp (dbx) nexti ungrasp +0x18: call support (dbx) |
For more information, see nexti Command and stepi Command.
Tracing techniques at the machine-instruction level work the same as at the source code level, except you use the tracei command For the tracei command, dbx executes a single instruction only after each check of the address being executed or the value of the variable being traced. The tracei command produces automatic stepi-like behavior: the program advances one instruction at a time, stepping into function calls.
When you use the tracei command, it causes the program to stop for a moment after each instruction while dbx checks for the address execution or the value of the variable or expression being traced. Using the tracei command can slow execution considerably.
For more information on trace and its event specifications and modifiers, see Tracing Execution and tracei Command.
Here is the general syntax for tracei:
tracei event-specification [modifier] |
Commonly used forms of tracei are:
For more information, see tracei Command.
To set a breakpoint at the machine-instruction level, use the stopi command. The command accepts any event specification, using the syntax:
stopi event-specification [modifier] |
Commonly used forms of the stopi command are:
stopi [at address] [-if cond] stopi in function [-if cond] |
For more information, see stopi Command.
To set a breakpoint at a specific address, type:
(dbx) stopi at address |
(dbx) nexti stopped in hand::ungrasp at 0x12638 (dbx) stopi at &hand::ungrasp (3) stopi at &hand::ungrasp (dbx) |
The adb command lets you enter commands in an adb(1) syntax. You can also enter adb mode which interprets every command as adb syntax. Most adb commands are supported.
For more information, see adb Command.
The regs command lets you print the value of all the registers.
Here is the syntax for the regs command:
regs [-f][-F] |
-f includes floating point registers (single precision). -F includes floating point registers (double precision). These are SPARC-only options.
For more information, see regs Command.
The following tables list platform-specific register names for SPARC and Intel that can be used in expressions.
The following register information is for SPARC systems.
The $f0f1 $f2f3 ... $f30f31 pairs of floating-point registers are treated as having C "double" type (normally $fN registers are treated as C "float" type). These pairs can also be referred to as $d0 ... $d30.
The following additional registers are available on SPARC V9 and V8+ hardware:
$g0g1 through $g6g7 $o0o1 through $o6o7 $xfsr $tstate $gsr $f32f33 $f34f35 through $f62f63 ($d32 ... $$d62) |
See the SPARC Architecture Reference Manual and the SPARC Assembly Language Reference Manual for more information on SPARC registers and addressing.
The following register information is for Intel systems.
Commonly used registers are also aliased to their machine independent names.
Registers for the 80386 lower halves (16 bits) are:
The first four 80386 16-bit registers can be split into 8-bit parts:
Copyright © 2002, Sun Microsystems, Inc. All rights reserved.