Register Identifiers
You can discover what machine registers are available on your processor architecture using the $r command. This example shows the output of $r on a SPARC system with the sun4 architecture:
kadb[0]: $r g0 0 l0 0 g1 100130a4 debug_enter l1 edd00028 g2 10411c00 tsbmiss_area+0xe00 l2 10449c90 g3 10442000 ti_statetbl+0x1ba l3 1b g4 3000061a004 l4 10474400 ecc_syndrome_tab+0x80 g5 0 l5 3b9aca00 g6 0 l6 0 g7 2a10001fd40 l7 0 o0 0 i0 0 o1 c i1 10449e50 o2 20 i2 0 o3 300006b2d08 i3 10 o4 0 i4 0 o5 0 i5 b0 sp 2a10001b451 fp 2a10001b521 o7 1001311c debug_enter+0x78 i7 1034bb24 zsa_xsint+0x2c4 y 0 tstate: 1604 (ccr=0x0, asi=0x0, pstate=0x16, cwp=0x4) pstate: ag:0 ie:1 priv:1 am:0 pef:1 mm:0 tle:0 cle:0 mg:0 ig:0 winreg: cur:4 other:0 clean:7 cansave:1 canrest:5 wstate:14 tba 0x10000000 pc edd000d8 edd000d8: ta %icc,%g0 + 125 npc edd000dc edd000dc: nop |
kadb exports each of these registers as a debugger variable with the same name. Reading from the variable fetches the current value of the register. Writing to the variable changes the value of the associated machine register. For example, you can change the value of the '%o0' register:
kadb[0]: <o0=K 0 kadb[0]: 0x1>o0 kadb[0]: <o0=K 1 |
Display and Control Commands
The following commands display and control the status of kadb(1M):
$b | Display all breakpoints |
$c | Display stack trace |
$d | Change default radix to value of dot |
$q | Quit |
$r | Display registers |
$M | Display built-in macros |
`$c' is useful when a breakpoint is reached, but is usually not useful if kadb(1M) is entered at a random time. The number of arguments to print can be passed following the `$c' (`$c 2' for two arguments).
Breakpoints
In kadb(1M), breakpoints can be set. When reached, the kernel will automatically drop back into kadb. The standard form of a breakpoint command is:
[module_name#] addr [, count]:b [command] |
addr is the address at which the program will be stopped and the debugger will receive control, count is the number of times that the breakpoint address occurs before stopping, and command is almost any adb(1) command.
The optional module_name specifies deferred breakpoints that are set when the module is loaded. module_name identifies a particular module that contains addr. If the module has been loaded, kadb will try to set a regular breakpoint; if the module is not loaded, kadb will set a deferred breakpoint. When the module is loaded, kadb will try to resolve the location of the breakpoint and convert the breakpoint to a regular breakpoint.
Other breakpoint commands are:
:c | Continue execution |
:d | Delete breakpoint |
:s | Single step |
:e | Single step, but step over function calls |
:u | Stop after return to caller of current function |
:z | Delete all breakpoints |
The following example sets a breakpoint in scsi_transport(9F), a commonly used routine. Upon reaching the breakpoint, '$c' is used to print a stack trace. The top of the stack is displayed first. Note that kadb does not know how many arguments were passed to each function.
stopped at edd000d8: ta %icc,%g0 + 125 kadb[0]: scsi_transport:b kadb[0]: :c test console login: root breakpoint at: scsi_transport: save %sp, -0x60, %sp kadb[0]: $c scsi_transport(702bb578,1000,1,10000,0,702bb7fe) sdstrategy(1019c8c0,702bb61c,0,0,702bb578,70cad7b8) + 704 bdev_strategy(1042a808,70cad7b8,705f3efc,40,10597900,2000) + 98 ufs_getpage_miss(70cad7b8,0,10597900,0,0,4023ba8c) + 2b0 ufs_getpage(0,0,0,0,2000,4023ba8c) + 7c0 segvn_fault(4023ba8c,2000,ff3b0000,0,0,0) + 7c8 as_fault(1,ff3b0000,70d98030,2000,0,ff3b0000) + 49c pagefault(0,0,70df8048,705c7450,0,ff3b0000) + 4c trap(10080,10000,ff3c4ea4,70df8048,ff3b0000,1) + db4 kadb[0]: $b breakpoints count bkpt type len command 1 scsi_transport :b instr 4 kadb[0]: scsi_transport:d kadb[0]: :c |
Conditional Breakpoints
Breakpoints can also be set to occur only if a certain condition is met. By providing a command, the breakpoint will be taken only if the count is reached or the command returns zero. For example, a breakpoint that occurs only on certain I/O controls could be set in the driver's ioctl(9E) routine. This is the general syntax of conditional breakpoints:
address,count:b command |
In this example, address is the address at which to set the breakpoint. count is the number of times the breakpoint should be ignored (note that 0 means break only when the command returns zero). command is the kadb(1M) command to execute.
Here is an example of breaking only in the sdioctl() routine if the DKIOGVTOC (get volume table of contents) I/O control occurs.
kadb[0]: sdioctl+4,0:b <i1-0x40B kadb[0]: $b breakpoints count bkpt type len command 0 sdioctl+4 :b instr 4 <i1-0x40B kadb[0]: :c |
Adding four to sdioctl skips to the second instruction in the routine, bypassing the save instruction that establishes the stack. The `<i1' refers to the first input register, which is the second parameter to the routine (the cmd argument of ioctl(9E)). The count of zero is impossible to reach, so it stops only when the command returns zero, which is when `i1 - 0x40B' is true. This means i1 contains 0x40B (the value of the ioctl(9E) command, determined by examining the ioctl definition).
To force the breakpoint to be reached, the prtvtoc(1M) command, which is known to issue the following I/O control, is used:
# prtvtoc /dev/rdsk/c0t0d0s0 breakpoint at: sdioctl+4: mov %i5, %l0 kadb[0]: $c sdioctl(800000,40b,ffbefb54,100005,704a3ce8,4026bc7c) + 4 ioctl(3,40b,70ca27b8,40b,ffbefb54,0) + 1e0 |