Solaris 模块调试器指南

bufctl 指针

包含在 buftag 区域中的缓冲区控制 (bufctl) 指针可以具有不同的含义,具体取决于高速缓存的 kmem_flags。 需要特别注意的是,KMF_AUDIT 标志的设置情况不同,具体的行为也会有所不同:如果设置 KMF_AUDIT 标志,则内核内存分配器会为每个缓冲区分配一个 kmem_bufctl_t 结构。 此结构包含有关每个缓冲区的一些最少记帐信息。 如果 设置了 KMF_AUDIT 标志,则分配器会改为分配 kmem_bufctl_audit_tkmem_bufctl_t 的扩展版本)。

本节假定已设置了 KMF_AUDIT 标志。对于未设置此位的高速缓存,可用的调试信息量会减少。

kmem_bufctl_audit_t(简称 bufctl_audit)包含有关此缓冲区中执行的最后一个事务的其他信息。以下示例说明了如何应用 bufctl_audit 宏检查审计记录。 所示的缓冲区是检测内存损坏中使用的示例缓冲区:

> 0x70a9ae00,5/KKn

0x70a9ae00:     5               4ef83

                0               0

                1               bbddcafe

                feedface        139d

                70ae3200        d1befaed

使用如上所述的方法可以很容易地看到 0x70ae3200 指向 bufctl_audit 记录:它是 redzone 后面的第一个指针。 要检查它所指向的 bufctl_audit 记录,请应用 bufctl_audit 宏:

> 0x70ae3200$<bufctl_audit

0x70ae3200:     next            addr            slab

                70378000        70a9ae00        707c86a0

0x70ae320c:     cache           timestamp       thread

                70039928        e1bd0e26afe     70aac4e0

0x70ae321c:     lastlog         contents        stackdepth

                7011c7c0        7018a0b0        4

0x70ae3228:

                kmem_zalloc+0x30

                pid_assign+8

                getproc+0x68

                cfork+0x60

'addr' 字段是对应于此 bufctl_audit 记录的缓冲区的地址。 以下是原始地址:0x70a9ae00。'cache' 字段是指已分配此缓冲区的 kmem_cache。可以使用 ::kmem_cache dcmd 对其进行检查,如下所示:

> 0x70039928::kmem_cache

ADDR     NAME                      FLAG  CFLAG  BUFSIZE  BUFTOTL

70039928 kmem_alloc_24             020f 000000       24      612

'timestamp' 字段表示执行此事务的时间。此时间的表示方式与 gethrtime(3C) 相同。

'thread' 是指向线程的指针,该线程在此缓冲区中执行了最后一个事务。 'lastlog' 和 'contents' 指针指向分配器的事务日志中的位置。 这些日志将在分配器日志记录工具中详细讨论。

通常,bufctl_audit 提供的最有用的信息段是事务发生时记录的栈跟踪。 在这种情况下,事务是在执行 fork(2) 的过程中调用的分配。