Writing Device Drivers

Displaying Data Structures with mdb

mdb provides a powerful facility for displaying kernel data structures, so that earlier kadb(1) and mdb(1) debugger macros are no longer needed. Starting in Solaris 9, the operating system kernel maintains a highly compressed database of data structure type information in nonpageable system memory. This means that when a crash occurs, this type information is saved as part of the crash dump.

Here is an example of using the kernel type information to display all of the fields of a scsi_pkt structure:


Example 18–5 Displaying Kernel Information with mdb

> 7079ceb0::print -t 'struct scsi_pkt'
{
    opaque_t pkt_ha_private = 0x7079ce20
    struct scsi_address pkt_address = {
        struct scsi_hba_tran *a_hba_tran = 0x70175e68
        ushort_t a_target = 0x6
        uchar_t a_lun = 0
        uchar_t a_sublun = 0
    }
    opaque_t pkt_private = 0x708db4d0
    int (*)() *pkt_comp = sd_intr
    uint_t pkt_flags = 0
    int pkt_time = 0x78
    uchar_t *pkt_scbp = 0x7079ce74
    uchar_t *pkt_cdbp = 0x7079ce64
    ssize_t pkt_resid = 0
    uint_t pkt_state = 0x37
    uint_t pkt_statistics = 0
    uchar_t pkt_reason = 0
}

Each data structure member is presented along with its type. Nested structures are expanded for easy viewing. ::print can also decode arrays and unions.

It is frequently helpful to discover the size of a particular kernel data structure; doing so is simple, using the ::sizeof dcmd:


> ::sizeof 'struct scsi_pkt'
sizeof (struct scsi_pkt) = 0x58

You can also locate the offset of a field within a data structure:


> ::offsetof 'struct scsi_pkt' pkt_state
offsetof (pkt_state) = 0x48

The -a option may be used to view the offset of each member of a data structure; if no address is specified to ::print, the output begins at address 0, providing the offset of each field:


Example 18–6 mdb: Viewing Data Members

> ::print -at 'struct scsi_pkt'

{
    0 opaque_t pkt_ha_private
    8 struct scsi_address pkt_address {
        8 struct scsi_hba_tran *a_hba_tran
        10 ushort_t a_target
        12 uchar_t a_lun
        13 uchar_t a_sublun
    }
    18 opaque_t pkt_private
    20 int (*)() *pkt_comp
    28 uint_t pkt_flags
    2c int pkt_time
    30 uchar_t *pkt_scbp
    38 uchar_t *pkt_cdbp
    40 ssize_t pkt_resid
    48 uint_t pkt_state
    4c uint_t pkt_statistics
    50 uchar_t pkt_reason
}

The ::print, ::sizeof and ::offsetof facilities make it possible to more rapidly debug problems which arise when your driver interacts with the Solaris kernel.


Caution – Caution –

This facility provides access to “raw” kernel data structures. You may examine any structure whether it appears as part of the DDI or not; therefore, refrain from relying on any data structure that is not explicitly part of the DDI.



Note –

These dcmds may only be used with objects that contain compressed symbolic debugging information designed for use with mdb. This information is currently only available for certain Solaris kernel modules. The SUNWzlib (32-bit) or SUNWzlibx (64-bit) decompression software must be installed in order to process the symbolic debugging information.