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_verify によれば、明らかに kmem_alloc_24 キャッシュには問題が存在します。明示的なキャッシュ引数を指定すると、::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 を調べることによって、このバッファにどのコードが最近書き込みを行なったか、どこでいつ解放されたかについての手がかりが得られます。

この状況でのもう 1 つの有用な手法は、::kgrep を使用してアドレス空間を調べてアドレス 0x702babc0 への参照を検索し、この解放されたデータへの参照を依然として保持しているスレッドまたはデータ構造体を発見することです。