Solaris モジューラデバッガ

カーネルメモリーキャッシュ

この節では、カーネルメモリーキャッシュを検索し調べる方法について説明します。::kmastat コマンドを実行することによって、システムの種々の kmem キャッシュについて調べることができます。

> ::kmastat
cache                        buf    buf    buf    memory     alloc alloc
name                        size in use  total    in use   succeed  fail
------------------------- ------ ------ ------ --------- --------- -----
kmem_magazine_1                8     24   1020      8192        24     0
kmem_magazine_3               16    141    510      8192       141     0
kmem_magazine_7               32     96    255      8192        96     0
...
kmem_alloc_8                   8   3614   3751     90112   9834113     0
kmem_alloc_16                 16   2781   3072     98304   8278603     0
kmem_alloc_24                 24    517    612     24576    680537     0
kmem_alloc_32                 32    398    510     24576    903214     0
kmem_alloc_40                 40    482    584     32768    672089     0
...
thread_cache                 368    107    126     49152    669881     0
lwp_cache                    576    107    117     73728       182     0
turnstile_cache               36    149    292     16384    670506     0
cred_cache                    96      6     73      8192   2677787     0
...

::kmastat を実行すれば、「正常な」システムの感じをつかむことができます。これは、システムのメモリーをリークしている過度に大きなキャッシュを見つけるのに役立ちます。::kmastat を実行した結果は、それを実行しているシステム、実行しているプロセスの数などによって異なります。

種々の kmem キャッシュのリストを表示するもう 1 つの方法は、::kmem_cache コマンドを使用することです。

> ::kmem_cache
ADDR     NAME                      FLAG  CFLAG  BUFSIZE  BUFTOTL
70036028 kmem_magazine_1           0020 0e0000        8     1020
700362a8 kmem_magazine_3           0020 0e0000       16      510
70036528 kmem_magazine_7           0020 0e0000       32      255
...
70039428 kmem_alloc_8              020f 000000        8     3751
700396a8 kmem_alloc_16             020f 000000       16     3072
70039928 kmem_alloc_24             020f 000000       24      612
70039ba8 kmem_alloc_32             020f 000000       32      510
7003a028 kmem_alloc_40             020f 000000       40      584
...

このコマンドは、キャッシュ名をアドレスに対応づける点で有用で、FLAG 欄には各キャッシュのデバッギングフラグが示されます。重要な点は、アロケータのデバッギング機能の選択がキャッシュごとにこのフラグのセットに基づいて行われていることです。これらは、キャッシュの作成時に、大域変数 kmem_flags とともに設定されます。システムの実行中に kmem_flags を設定しても、そのあとに作成されたキャッシュを除いて (起動後にキャッシュが作成されることはまれです)、デバッギング動作には影響を与えません。

次に、MDB の kmem_cache walker を使用して、直接 kmem キャッシュのリストを調べます。

> ::walk kmem_cache
70036028
700362a8
70036528
700367a8
...

これによって、カーネルの各 kmem キャッシュに対応するポインタのリストが作成されます。特定のキャッシュを見つけるには、kmem_cache マクロを適用します。

> 0x70039928$<kmem_cache
0x70039928:     lock
0x70039928:     owner/waiters
                0
0x70039930:     flags           freelist        offset
                20f             707c86a0        24
0x7003993c:     global_alloc    global_free     alloc_fail
                523             0               0
0x70039948:     hash_shift      hash_mask       hash_table
                5               1ff             70444858
0x70039954:     nullslab
0x70039954:     cache           base            next
                70039928        0               702d5de0
0x70039960:     prev            head            tail
                707c86a0        0               0
0x7003996c:     refcnt          chunks
                -1              0
0x70039974:     constructor     destructor      reclaim
                0               0               0
0x70039980:     private         arena           cflags
                0               104444f8        0
0x70039994:     bufsize         align           chunksize
                24              8               40
0x700399a0:     slabsize        color           maxcolor
                8192            24              32
0x700399ac:     slab_create     slab_destroy    buftotal
                3               0               612
0x700399b8:     bufmax          rescale         lookup_depth
                612             1               0
0x700399c4:     kstat           next            prev
                702c8608        70039ba8        700396a8
0x700399d0:     name    kmem_alloc_24
0x700399f0:     bufctl_cache    magazine_cache  magazine_size
                70037ba8        700367a8        15
...

デバッギングにとって重要なフィールドは、「bufsize」、「flags」、および「name」です。kmem_cache の名前 (この場合は「kmem_alloc_24」) は、このシステムでの目的を示しています。bufsize は、このキャッシュの各バッファーのサイズです。この場合、このキャッシュはサイズ 24 以下の割り当てに使用されます。「flags」は、このキャッシュに対してどのデバッギング機能が有効になっているかを示しています。これは <sys/kmem_impl.h> の中に定義されているデバッギングフラグです。この場合には「flags」は 0x20f ですが、これは KMF_AUDIT | KMF_DEADBEEF | KMF_REDZONE | KMF_CONTENTS | KMF_HASH です。各デバッギング機能については、この後の各節で説明します。

特定のキャッシュのバッファーを調べたい場合には、そのキャッシュの割り当て済みおよび未使用バッファーを直接調べることができます。

> 0x70039928::walk kmem
704ba010
702ba008
704ba038
702ba030
...

> 0x70039928::walk freemem
70a9ae50
70a9ae28
704bb730
704bb2f8
...

MDB は、kmem walker にキャッシュアドレスを供給するショートカットを用意しています。kmem キャッシュごとに特定の walker が提供され、その walker の名前はキャッシュの名前と同じです。次にその例を示します。

> ::walk kmem_alloc_24
704ba010
702ba008
704ba038
702ba030
...

> ::walk thread_cache
70b38080
70aac060
705c4020
70aac1e0
...

これで、カーネルメモリーアロケータの内部データ構造体に対して繰り返す方法や、kmem_cache データ構造体のもっとも重要なメンバーを調べる方法がわかります。