kadb(1M) supports macros that are used for displaying kernel data structures. kadb macros can be displayed with $M. Macros are used in the form:
[ address ] $<macroname
Neither the information displayed by these macros, nor the format in which the information is displayed constitute an interface. Therefore, the information and format can change at any time.
This section describes the kadb(1M) macros that can be used to retrieve information from the kernel about a device during a debugging session.
devinfo_brief |
Prints a brief summary of a dev_info_t structure; the name and addr fields are shown in string form and are used in the /devices path to the node |
devinfo |
Prints devinfo_brief information for a dev_info_t structure followed by an in-order dump of all fields |
devinfo.parent |
Prints devinfo_brief information for the specified node and its parents all the way back to the root of the devinfo tree |
devinfo.sibling |
Prints devinfo_brief information for all siblings of the specified node; you see all sibling nodes if you start at the parent's child |
devinfo.minor |
Prints the ddi_minor_data structure for all minor name nodes associated with the specified device node |
devinfo.prop |
Prints all the property lists associated with the specified device node |
devinfo_major |
Prints devinfo_brief information for all device nodes associated with the specified driver major number |
devt |
Breaks a dev_t into its major and minor parts and prints the values in hexadecimal and decimal |
devnames |
Prints the contents of the specified devnames structure |
devnames_major |
Prints the contents of the devnames structure for the specified major number |
bus_op |
Prints the contents of a bus_ops structure |
The devinfo commands, such as devinfo and devinfo_brief, return a node_state value, which may be one of the following:
This device node has been linked into the kernel's device tree, but the system has not yet found a driver for it.
The node is bound to a driver, but the driver's probe(9E) routine has not yet been called.
The parent nexus has assigned a bus address for the driver and completed implementation-specific initializations, but the driver's probe(9E) routine has not yet been called.
The driver's probe(9E) routine returned successfully.
The driver's attach(9E) routine returned successfully.
The device is fully configured.
The examples in this section show how some of the device-related macros can be used to debug a driver.
The following ls -l command shows how the /devices path fits into the devinfo structure:
# ls -l /dev/ttya lrwxrwxrwx 1 root root 6 Aug 17 17:50 /dev/ttya -> term/a # ls -l /dev/term/a lrwxrwxrwx 1 root root 32 Aug 17 17:42 /dev/term/a -> ../../devices/obio/zs@0,100000:a
Example 18–1 shows how to obtain information about the /dev/ttya device from the devinfo structure and other kernel structures, beginning with devinfo_major.
# ls -lL /dev/ttya crw-rw-rw- 1 root sys 29, 0 Aug 17 17:42 /dev/ttya # ~stopped at: edd000d8: ta %icc,%g0 + 125 kadb[0]: 0t29$<devinfo_major ============== devinfo f5f0dcd0 binding_name 0xf5bb38f8: zs node_name 0xf5bb38f8: zs addr 0xf5f8d6a0: 0,100000 node_state 6 DS_READY major (hex) 1d instance 0 0xf5f0dcd0: parent child sibling f5f0f380 0 f5f0dba8 ============== devinfo f5f0dba8 binding_name 0xf5bb3a18: zs node_name 0xf5bb3a18: zs addr 0xf5f90560: 0,0 node_state 6 DS_READY major (hex) 1d instance 1 0xf5f0dba8: parent child sibling f5f0f380 0 f5f0da80
Example 18–2 shows the use of the devinfo_brief macro. It also shows the use of top_devinfo. top_devinfo is a pointer to the root of the devinfo tree (rootnexus)—all other devinfo nodes are descendants of this node. If you want to look at the device tree top-down in the debugger, this is where you start.
kadb[0]: *top_devinfo$<devinfo_brief ============== devinfo f5f0fde8 binding_name 0xf5bc6a30: SUNW,SPARCstation-10 node_name 0xf5bc6af8: SUNW,SPARCstation-10 addr 0xf5f90950: node_state 6 DS_READY major (hex) 1 0xf5f0fde8: parent child sibling 0 f5f0fcc0 0
threadlist is a useful macro that displays the stacks of all the threads in the system.
kadb[0]: $<threadlist ============== thread_id 10404000 p0+0x300: process args sched t0+0xa8: lwp procp wchan 1041b810 10424688 0 t0+0x24: pc sp sched+0x4f4 10403be8 ?(10404000,1040c000,2,10424604,0,6e) _start(10006ef4,1041adb0,1041adb0,1041adb0,10462910,50) + 15c ... ============== thread_id 40043e60 p0+0x300: process args sched 40043f08: lwp procp wchan 0 10424688 10473c56 40043e84: pc sp cv_wait+0x60 40043c08 ?(10473c56,10473c5c,0,40043cd0,40043e60,10093084) ufs_thread_idle(10471e80,0,10473c5c,10424688,81010100,0) + bc thread_start(0,0,0,0,0,0) + 4 ...
Another useful macro is thread. Given a thread ID, this macro prints the corresponding thread structure. This can be used to look at a certain thread found with the threadlist macro, to look at the owner of a mutex, or to look at the current thread, as shown here:
kadb[0]: <g7$<thread 70e87ac0: link stk startpc 0 4026bc80 0 70e87acc: bound_cpu affinitycnt bind_cpu 0 0 -1 70e87ad4: flag proc_flag schedflag 0 4 3 70e87ada: preempt preempt_lk state 0 0 4 70e87ae0: pri epri 40 0 70e87ae4: pc sp 10098350 4026b618 70e87aec: wchan0 wchan sobj_ops 0 0 0 70e87af8: cid clfuncs cldata 1 10470ffc 702c0488 70e87b04: ctx lofault onfault 0 0 0 ...
No type information is maintained by kadb, so using a macro on an inappropriate address results in garbage output.
Macros do not necessarily output all the fields of the structures, nor is the output necessarily in the order given in the structure definition. Occasionally, memory needs to be dumped for certain structures and then matched with the structure definition in the kernel header files.
Drivers should never reference system header files or structures not listed in man pages section 9S: DDI and DKI Data Structures. However, examining non-DDI-compliant structures (such as thread structures) can be useful in debugging drivers.