Solaris 模块调试器指南

使用 ::kmem_verify 查找损坏的缓冲区

MDB 的 ::kmem_verify dcmd 在运行时可实现大多数 kmem 分配器实现的检查。可以调用 ::kmem_verify 以便扫描每个具有相应 kmem_flags 的 kmem 内存,或者检查特定的高速缓存。

以下是使用 ::kmem_verify 确定问题的示例:

> ::kmem_verify

Cache Name                      Addr     Cache Integrity

kmem_alloc_8                    70039428 clean

kmem_alloc_16                   700396a8 clean

kmem_alloc_24                   70039928 1 corrupt buffer

kmem_alloc_32                   70039ba8 clean

kmem_alloc_40                   7003a028 clean

kmem_alloc_48                   7003a2a8 clean

...

在这里可以很容易地看到 kmem_alloc_24 高速缓存包含 ::kmem_verify 所确认的问题。使用显式的高速缓存参数,::kmem_verify dcmd 可以提供有关该问题的更详细信息:

> 70039928::kmem_verify

Summary for cache 'kmem_alloc_24'

  buffer 702babc0 (free) seems corrupted, at 702babc0

下一步是检查 ::kmem_verify 确认已损坏的缓冲区:

> 0x702babc0,5/KKn

0x702babc0:     0               deadbeef

                deadbeef        deadbeef

                deadbeef        deadbeef

                feedface        feedface

                703785a0        84d9714e

::kmem_verify 标记此缓冲区的原因此时非常明显:缓冲区中的第一个字(位于 0x702babc0)可能应该使用 0xdeadbeef 模式而不是 0 填充。 此时,为此缓冲区检查 bufctl_audit 可能产生有关最近向缓冲区写入了哪些代码的线索,指明释放此缓冲区的位置和时间。

此情况下的另一种有用方法是使用 ::kgrep 在地址空间中搜索对地址 0x702babc0 的引用,以便发现哪些线程或数据仍然包含对此已释放数据的引用。