dbx コマンドによるデバッグ

コマンド参照

check|uncheck

以下に、checkuncheck の形式を示します。

RTC の現在の状態を出力します。


check

アクセス検査を行います。


check -access

リーク検査を行います。


check -leaks [-frames n] [-match m]

-frames n

リークしたブロックの割り当て追跡を表示するときのスタックフレームの最大数 n を指定します。

-match m

リークをまとめるのに使用します。呼び出しスタックが 2 つ以上のリークを割り当てる際に m 個のフレームと一致した場合は、リークは 1 つにまとめて報告されます。

n のデフォルト値は 8 か m の値 (どちらか大きい方) になり、最大値は 16 です。m のデフォルト値は 2 です。

check -memuse には check -leaks の意味も含まれています。プログラム終了時には、リークレポートに加えて、メモリー使用状況レポートも出力されます。プログラム実行中に、プログラムのメモリーがどこに割り当てられているかをいつでも見ることができます。

メモリー使用状況検査をオンにするには、次のように入力します。


check -memuse [-frames n] [-match m]

-frames n

使用中ブロックの割り当てトレースを示すときに、最大 n 個の明確なスタックフレームが一覧表示されます。

-match m

プログラム内に多数の使用中ブロックが存在する可能性があるため、RTC は、同じ実行トレースから割り当てられたブロックを自動的に 1 つのレポートに結合します。レポートを結合するための決定は、m の値によって指定されます。複数ブロックの割り当て時の呼び出しスタックが m フレームと一致する場合、これらのブロックは、結合された使用中ブロックレポートで報告されます。ブロックの結合方法は、リークレポートで使用される方式と似ています。

n のデフォルト値は 8 または m の値のどちらか大きい方です。n の最大値は 16 です。m のデフォルト値は 2 です。

次の 2 つのコマンドは同じ結果になります。


check -all [-frames n] [-match m]
check -access ; check -memuse [-frames n] [-match m]

アクセス検査をオフにします。


uncheck -access

リーク検査をオフにします。


uncheck -leaks

メモリー使用状況検査をオフにします (リーク検査もオフになります)。


uncheck -memuse

次の 2 つのコマンドは同じ結果になります。


uncheck -all
uncheck -access; uncheck -memuse

次の 2 つのコマンドは同じ結果になります。


uncheck [funcs] [files] [loadobjects]
suppress all in funcs files loadobjects

check コマンドの次の形式を使用すると、特定の関数の集合 function*、モジュール file*、ロードオブジェクト loadobject* 内だけで検査をオンにし、プログラムの残りの部分では検査をオフにすることができます。


check function* file* loadobject*

このコマンドは、次と同じ働きをします。


suppress all
unsuppress all in function* file* loadobject*

check コマンドは累計的に機能します。たとえば、次の初めの 3 つのコマンドは、その後の 4 つのコマンドと同じ結果になります。


check main
check foo
check f.c

suppress all
unsuppress all in main
unsuppress all in foo
unsuppress all in f.c

suppress all コマンドは一度だけ適用され、mainfoof.c では検査がオンのままになります。

次の 2 つのコマンドは同じ結果になります。


uncheck function* file* loadobject
suppress all in function* file* loadobject*

showblock


showblock -a addr

メモリー使用状況検査またはメモリーリーク検査がオンになっている場合、showblock は、アドレス addr にあるヒープブロックに関する詳細を示します。この詳細には、ブロックの割り当て位置とそのサイズが含まれます。

showleaks

最後の showleaks コマンド以降の新しいメモリーリークを報告するには、次のように入力します。


showleaks [-a] [-m m] [-n num] [-v]

デフォルトの簡易レポートでは、リークレコードごとに 1 行のレポートが出力されます。実際のリークに続けて可能性のあるリークが報告されます。レポートは、リークの結合サイズに従ってソートされます。

-a

これまでに発生したリークがすべて表示されます (前回の showleaks コマンドを実行した後のものだけではありません)。

-m m

リークをまとめるのに使用します。呼び出しスタックが 2 つ以上のリークを割り当てる際に m 個のフレームと一致した場合は、リークは 1 つにまとめて報告されます。-m オプションを指定すると、check コマンドで指定した m の大域値が無効になります。m のデフォルト値は 2 または check コマンドで大域値として指定した最新の値のどちらかです。

-n num

最大 num のレコードをレポートに示します。デフォルトでは、すべてのレコードが表示されます。

-v

詳細出力を生成します。デフォルトでは、簡易出力が示されます。 

showmemuse

このコマンドを実行すると、使用中のメモリーブロックがすべて表示されます。


showmemuse [-a] [-m m] [-n num] [-v]

使用中のブロックの上位 num 個をサイズでソートして報告します。前回 showmemuse コマンドを実行した後のブロックのみ表示されます。

-a

現時点までの使用中ブロックすべてを示します。 

-m m

使用中ブロックレポートの結合に使用します。複数ブロックの割り当て時の呼び出しスタックが m フレームに一致する場合、それらのブロックは単一の結合レポートで報告されます。-m オプションは、check コマンドに指定された m の大域値を無効にします。m のデフォルト値は 2 か、または check で最後に指定された大域値になります。

-n num

最大 num 個のレコードをレポートに示します。デフォルトでは 20 個のレコードが示されます。

-v

詳細出力を生成します。デフォルトでは、簡易出力が示されます。 

メモリー使用のチェックをオンにすると、プログラムの終了時 showmemuse -a -n 20 が暗黙的に実行されます。rtc_biu_at_exit dbxenv 変数を使用することにより、プログラムの終了時に詳細報告を出力できます。

suppress|unsuppress

ロードオブジェクト loadobject 中のファイルは、-g 付きでコンパイルされないことがあります。これは、そのファイル中の関数にデバッグ情報がないことを表します。RTC はこのような場合にデフォルトの抑止を使用します。location_specifier は位置指定子です。

デフォルトの抑止の一覧を得るには、


{suppress | unsuppress} -d

1 つのロードオブジェクトについてデフォルトの抑止を変更するには、


{suppress | unsuppress} -d [error type] [in loadobject]

すべてのロードオブジェクトについてデフォルトの抑止を変更するには、


{suppress | unsuppress} -d [error type]

設定をデフォルトに戻すには、


suppress -reset

次のコマンドは、最新エラーを抑止または抑止解除するために使用します。このコマンドは、アクセスエラーにのみ適用され、リークエラーには適用されません。


{suppress | unsuppress} -last

-d および -reset コマンドを含まない抑止コマンドの履歴を表示するには、次のように入力します。


{suppress | unsuppress}

指定位置の指定エラータイプについてのエラーレポートをオンまたはオフにします。


{suppress | unsuppress} [ error type... [ location_specifier ]]

id によって指定された suppress または unsuppress イベントを削除するには、次のように入力します。


suppress -r id...

suppress によって指定された抑止イベントと抑止解除イベントをすべて削除するには、次のように入力します。


suppress -r [0 | all | -all]

エラータイプの位置指定子

次の表にエラータイプの位置指定子を示します。

in loadobject

指定したプログラムやライブラリに含まれるすべての関数 (*) 

in file

指定のファイル内のすべての関数 

in function

指定の関数 

at line specifier

ソース内の特定の行 

addr address

指定の 16 進アドレス 

ロードオブジェクトの一覧を参照したい場合は、dbx のプロンプトで loadobjects と入力します。位置指定子が指定されない場合は、プログラムは大域的に検索されます。位置指定子はコマンドごとに使用できます。

RTC エラー

ブロック中のアドレス (aib)

意味 : メモリーリークの可能性がある。割り当てブロックの先頭への参照はないが、そのブロック内のアドレスへの参照が少なくとも 1 つ存在する。 

考えられる原因 : そのブロックの先頭を指す唯一のポインタが増分された。 

例 :


char *ptr;
main()
{
       ptr = (char *)malloc(4);
       ptr++;           /* ブロック中のアドレス (aib) */
}

レジスタ中のアドレス (air)

意味 : メモリーリークの可能性がある。割り当てられたブロックが解放されておらず、そのブロックへの参照がプログラム内のどこにも存在しない。 

考えられる原因 : 割り当てられているブロックへの唯一の参照は、レジスタ内に含まれています。このようなことは、コンパイラがプログラム変数をメモリー内ではなくレジスタ内だけに保持している場合に発生し、その動作は正しいこともあります。最適化がオンになっている場合、コンパイラは局所変数や関数パラメータに対してこのような操作をよく行います。最適化がオンになっていないときにこのエラーが発生した場合は、実際のメモリーリークが考えられます。たとえば、割り当てられているブロックへの唯一のポインタが、そのブロックの解放前にスコープ外に出た場合にこのエラーが発生します。 

例 :


      if (i == 0) {
            char *ptr = (char *)malloc(4);
            /* ポインタがスコープ外に出た */
      }
    /* メモリーリークまたはレジスタ中のアドレス (air) */

不正解放 (baf)

意味 : 割り当てられたことのないメモリーを解放しようとした。 

考えられる原因 : free() または realloc() にヒープデータ以外のポインタを渡した。

例 :


      char a[4];
      char *b = &a[0];

      free(b);           /* 不正解放 (baf) */

重複解放 (duf)

意味 : すでに解放されているヒープブロックを解放しようとした。 

考えられる原因 : 同じポインタを使用して free() を 2 回以上呼び出した。C++ では、同じポインタに対して“delete”演算子を 2 回以上使用した。

例 :


      char *a = (char *)malloc(1);
      free(a);
      free(a);               /* 重複解放 (duf) */

境界整列を誤った解放 (maf)

意味 : 境界合わせされていないヒープブロックを解放しようとした。 

考えられる原因 : free() または realloc() に正しく境界合わせされていないポインタを渡した。malloc によって返されたポインタを変更した。

例 :


      char *ptr = (char *)malloc(4);
      ptr++;
      free(ptr);               /* 境界整列を誤った解放 (maf) */

境界整列を誤った読み取り (mar)

意味 : 適切に境界合わせされていないアドレスからデータを読み取ろうとした。 

考えられる原因 : ハーフワード、ワード、ダブルワードの境界に合わせられていないアドレスから、それぞれ 2 バイト、4 バイト、8 バイトを読み取った。 

例 :


      char *s = ”hello world”;
      int *i = (int *)&s[1];
      int j;

      j = *i;           /* 境界整列を誤った読み取り (mar) */

境界整列を誤った書き込み (maw)

意味 : 適切に境界合わせされていないアドレスにデータを書き込もうとした。 

考えられる原因 : ハーフワード、ワード、ダブルワードの境界に合わせられていないアドレスに、それぞれ 2 バイト、4 バイト、8 バイトを書き込んだ。 

例 :


      char *s = ”hello world”;
      int *i = (int *)&s[1];

      *i = 0;           /* 境界整列を誤った書き込み (maw) */

メモリーリーク (mel)

意味 : 割り当てられたブロックが解放されておらず、そのブロックへの参照がプログラム内のどこにも存在しない。 

考えられる原因 : プログラムが使用されなくなったブロックを解放しなかった。 

例 :


char *ptr;
   ptr = (char *)malloc(1);
   ptr = 0;
/* メモリーリーク (mel) */

メモリー不足 (oom)

意味 : 利用可能な物理メモリーより多くのメモリーを割り当てようとした。 

考えられる原因 : プログラムがこれ以上システムからメモリーを入手できない。oom エラーは、malloc() からの戻り値が NULL かどうか検査していない (プログラミングでよく起きる誤り) ために発生する問題の追跡に役立ちます。

例 :


      char *ptr = (char *)malloc(0x7fffffff);
      /* メモリー不足 (oom), ptr == NULL */

非割り当てメモリーからの読み取り (rua)

意味 : 存在しないメモリー、割り当てられていないメモリー、マップされていないメモリーからデータを読み取ろうとした。 

考えられる原因 : ストレイポインタ (不正な値を持つポインタ)、ヒープブロック境界のオーバーフロー、すでに解放されたヒープブロックへのアクセス。 

例 :


      char c, *a = (char *)malloc(1);
      c = a[1];  /* 非割り当てメモリーからの読み取り (rua) */

非初期化メモリーからの読み取り (rui)

意味 : 初期化されていないメモリーからデータを読み取ろうとした。 

考えられる原因 : 初期化されていない局所データまたはヒープデータの読み取り。 

例 :


      foo()
      {   int i,  j;
          j = i;  /* 非初期化メモリーからの読み取り (rui) */
      }

読み取り専用メモリーへの書き込み (wro)

意味 : 読み取り専用メモリーにデータを書き込もうとした。 

考えられる原因 : テキストアドレスへの書き込み、読み取り専用データセクション (.rodata) への書き込み、読み取り専用として mmap されているページへの書き込み。

例 :


      foo()
      {  int *foop = (int *) foo;
         *foop = 0;/* 読み取り専用メモリーへの書き込み (wro) */
      }

非割り当てメモリーへの書き込み (wua)

意味 : 存在しないメモリー、割り当てられていないメモリー、マップされていないメモリーにデータを書き込もうとした。 

考えられる原因 : ストレイポインタ、ヒープブロック境界のオーバーフロー、すでに解放されたヒープブロックへのアクセス。 

例 :


      char *a = (char *)malloc(1);
      a[1] = `¥0';/* 非割り当てメモリーへの書き込み (wua) */

dbxenv 変数

RTC 環境の設定には、次の dbxenv 変数を使用してください。これらの変数のいずれかをそのデフォルト値から永続的に変更したい場合は、dbxenv コマンドを $HOME/.dbxrc ファイルに入れます。すると、RTC を使用するときに必ず、各自の指定した値が使用されます。

dbxenv rtc_auto_continue {on | off}

rtc_auto_continue on にすると、RTC はエラーを見つけたところで停止せず、実行を継続します。また、すべてのエラーは $errorlogfile で指定されたファイルにリダイレクトされます。デフォルトは off です。

dbxenv rtc_auto_suppress {on | off}

rtc_auto_suppresson にすると、特定のエラーがある場所で最初見つかったときに報告され、その後同じエラーについては抑止されます。この機能は、同じエラーに対して重複して報告されないようにするのに便利です。デフォルトは on です。

dbxenv rtc_biu_at_exit {on | off | verbose}

この変数は check -memuse が有効 (暗黙的または check -all を使ってオンにしている) の場合に使用されます。この変数の値が on の場合、プログラム終了時に簡単なメモリー使用状況 (ブロック使用状況) レポートが生成されます。デフォルトは on です。

値が verbose の場合、プログラム終了時に詳細なメモリー使用状況レポートが生成されます。値を off にすると、何も出力されません。この変数は、対話形式の showmemuse コマンドに影響を及ぼしません。

dbxenv rtc_error_log_file_name {filename}

rtc_error_log_file_name は、RTC エラーメッセージを dbx の標準出力の代わりに指定されたファイル filename にリダイレクトします。デフォルト は /tmp/dbx.errlog.uniqueid です。

実行時エラーがバッチモードで検出された場合は、プログラムは自動的に停止しません。すべてのエラー出力は filename に格納されます。プログラムは、ブレークポイントを検出するか割り込みが行われると停止します。

バッチモードでは、完全なスタックバックトレースが生成され、filename にリダイレクトされます。すべてのエラーを端末にリダイレクトするには、rtc_error_log_file_name /dev/tty に設定してください。

dbxenv rtc_error_limit n

ここで、n は RTC が報告するエラーの最大数です。このエラーの制限値は、アクセスエラーとリークエラーとで別々に使用されます。たとえば、エラーの制限値を 5 に設定すると、プログラムの実行の最後に行われるリークレポートと実行する各 showleaks コマンドの両方で、最大 5 つのアクセスエラーと最大 5 つのメモリーリークが示されます。デフォルトは 1000 です。

dbxenv rtc_mel_at_exit {on|off|verbose}

この変数は、リーク検査が有効な場合に使用されます。変数の値が on の場合、簡易メモリーリークレポートがプログラムの終了時に作成されます。変数の値が verbose だと、詳細メモリーリークレポートがプログラムの終了時に作成されます。値が off の場合、出力は生成されません。この変数は、showleaks コマンドには影響を及ぼしません。デフォルト値は on です。