bufctl
指针包含在 buftag 区域中的缓冲区控制 (bufctl) 指针可以具有不同的含义,具体取决于高速缓存的 kmem_flags。 需要特别注意的是,KMF_AUDIT 标志的设置情况不同,具体的行为也会有所不同:如果未设置 KMF_AUDIT 标志,则内核内存分配器会为每个缓冲区分配一个 kmem_bufctl_t 结构。 此结构包含有关每个缓冲区的一些最少记帐信息。 如果已 设置了 KMF_AUDIT 标志,则分配器会改为分配 kmem_bufctl_audit_t(kmem_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) 的过程中调用的分配。