Sun Studio 12: dbx コマンドによるデバッグ

メモリーリークの報告を理解する

リーク検査を有効にすると、プログラムの終了時にリークレポートが自動的に生成されます。kill コマンドでプログラムを終了した場合を除き、リークの可能性がすべて報告されます。レポートの詳細レベルは、dbx 環境変数 rtc_mel_at_exit (dbx 環境変数の設定」を参照) で制御します。デフォルトで、非冗長リークレポートが生成されます。

レポートは、リークのサイズによってソートされます。実際のメモリーリークが最初に報告され、次に可能性のあるリークが報告されます。詳細レポートには、スタックトレース情報の詳細が示されます。 行番号とソースファイルが使用可能であれば、これらも必ず含まれます。

次のメモリーリークエラー情報が、2 種類の報告のどちらにも含まれます。

情報 

内容の説明 

サイズ 

リークしたブロックのサイズ 

場所 

リークしたブロックが割り当てられた場所 

アドレス 

リークしたブロックのアドレス 

スタック 

割り当て時の呼び出しスタック。 check -frames によって制約される

次に、対応する簡易メモリーリークレポートを示します。


実際のリークの報告      (実際のリーク:        3  合計サイズ:      2427 バイト)

 合計       ブロック   リーク      割り当て呼び出しスタック
 サイズ      数      ブロック
                          アドレス
==========   ======     ==========    =======================================
    1852     2    -       true_leak < true_leak
     575     1   0x22150  true_leak < main

起こり得るリークの報告    (起こり得るリーク:      1  合計サイズ:      8 バイト)
 合計       ブロック   リーク         割り当て呼び出しスタック
 サイズ      数      ブロック
                             アドレス
==========   ======     ==========      =======================================
      8      1    0x219b0    in_block < main

次に、典型的な詳細リークレポートを示します。


実際のリークの報告      (実際のリーク:        3  合計サイズ:      2427 バイト)

メモリーリーク (mel):
大きさ 1 バイトのリークのあるブロックをアドレス 0x20f18 に発見
割り当て時のスタックの状態:
        [1] true_leak()   行番号  220 "leaks.c"
        [2] true_leak()   行番号  224 "leaks.c"

メモリーリーク (mel):
大きさ 575 バイトのリークのあるブロックをアドレス 0x22150 に発見
割り当て時のスタックの状態:
        [1] true_leak()   行番号  220 "leaks.c"
        [2] main()        行番号  87 "leaks.c"

起こり得るリークの報告    (起こり得るリーク:      1  合計サイズ:      8 バイト)

メモリーリークの可能性 -- ブロック中のアドレス (aib):
大きさ 4 バイトのリークのあるブロックをアドレス 0x219b0 に発見
割り当て時のスタックの状態:
        [1] in_block()    行番号  177 "leaks.c"
        [2] main()        行番号  100 "leaks.c"

リークレポートの生成

showleaks コマンドを使用すると、いつでもリークレポートを要求することができます。このコマンドは、前回の showleaks コマンド以降の新しいメモリーリークを報告するものです。詳細については、showleaks コマンド」を参照してください。

リークレポート

リークレポートの数が多くなるのを避けるため、RTC は同じ場所で割り当てられたリークを自動的に 1 つにまとめて報告します。1 つにまとめるか、それぞれ各リークごとに報告するかは、一致フレーム数引数によって決まります。この引数は、check -leaks コマンドを実行する際は -match m オプション、showleaks コマンドを実行する際は -m オプションで指定します。呼び出しスタックが 2 つ以上のリークを割り当てる際に m 個のフレームと一致した場合は、リークは 1 つにまとめて報告されます。

次の 3 つの呼び出しシーケンスを考えてみます。

ブロック 1 

ブロック 2 

ブロック 3 

[1] malloc

[1] malloc

[1] malloc

[2] d() at 0x20000

[2] d() at 0x20000

[2] d() at 0x20000

[3] c() at 0x30000

[3] c() at 0x30000

[3] c() at 0x31000

[4] b() at 0x40000

[4] b() at 0x41000

[4] b() at 0x40000

[5] a() at 0x50000

[5] a() at 0x50000

[5] a() at 0x50000

これらのブロックがすべてメモリーリークを起こす場合、m の値によって、これらのリークを別々に報告するか、1 つのリークが繰り返されたものとして報告するかが決まります。m が 2 のとき、ブロック 1 とブロック 2 のリークは 1 つのリークが繰り返されたものとして報告されます。 これは、malloc() の上にある 2 つのフレームが共通しているためです。ブロック 3 のリークは、c() のトレースがほかのブロックと一致しないので別々に報告されます。m が 2 よりも大きい場合、RTC はすべてのリークを別々に報告します (malloc はリークレポートでは表示されません)。

一般に、m の値が小さければリークのレポートもまとめられ、m の値が大きければまとめられたリークレポートが減り、別々のリークレポートが生成されます。