Oracle Solaris Studio 12.2: dbx コマンドによるデバッグ

RTC エラー

RTC で報告されるエラーは、通常はアクセスエラーとリークの 2 種類があります。

アクセスエラー

アクセス検査がオンのとき、RTC による検出と報告の対象になるのは次のタイプのエラーです。

不正解放 (baf) エラー

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

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

次に例を示します。

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

free(b);                    /* Bad free (baf) */

重複解放 (duf) エラー

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

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

次に例を示します。

char *a = (char *)malloc(1);
free(a);
free(a);                    /* Duplicate free (duf) */

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

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

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

次に例を示します。

char *ptr = (char *)malloc(4);
ptr++;
free(ptr);                    /* Misaligned free */

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

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

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

次に例を示します。

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

j = *i;                    /* Misaligned read (mar) */

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

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

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

次に例を示します。

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

*i = 0;                    /* Misaligned write (maw) */

メモリー不足 (oom) エラー

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

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

次に例を示します。

char *ptr = (char *)malloc(0x7fffffff);
/* Out of Memory (oom), ptr == NULL */

配列範囲外からの読み込み (rob) エラー

意味: 配列範囲外のメモリーからデータを読み取ろうとした。

考えられる原因: 浮遊ポインタ、ヒープブロックの範囲からあふれ出ている。

次に例を示します。

char *cp = malloc (10);
char ch = cp[10];

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

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

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

次に例を示します。

char *cp = malloc (10);
free (cp);
cp[0] = 0;

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

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

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

次に例を示します。

foo()
{   int i, j;
    j = i;    /* Read from uninitialized memory (rui) */
}

配列範囲外メモリーへの書き込み (wob) エラー

意味: 配列範囲外のメモリーにデータを書き込もうとした。

考えられる原因: 浮遊ポインタ、ヒープブロックの範囲からあふれ出ている。

次に例を示します。

char *cp = malloc (10);
cp[10] = 'a';

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

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

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

次に例を示します。

foo()
{   int *foop = (int *) foo;
    *foop = 0;                /* Write to read-only memory (wro) */
}

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

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

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

次に例を示します。

char *cp = malloc (10);
free (cp);
cp[0] = 0;

メモリーリークエラー

リーク検査をオンにしておくと、RTC では次のエラーが報告されます。

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

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

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

例 :

char *ptr;
main()
{
   ptr = (char *)malloc(4);
   ptr++;    /* Address in Block */
}

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

意味: メモリーリークの可能性がある。割り当てられたブロックが解放されておらず、そのブロックに対する参照がプログラムのどこにもないが、レジスタには参照がある。

考えられる原因: コンパイラがプログラム変数をメモリーではなくレジスタにだけ保存している場合にこのエラーになる。最適化をオンにしてコンパイラを実行すると、局所変数や関数パラメータにこのような状況がよく発生する。最適化をオンにしていないのにこのエラーが発生する場合は、メモリーリークが疑われる。ブロックを解放する前に、割り当てられたブロックに対する唯一のポインタが範囲外を指定するとメモリーリークになる。

次に例を示します。

if (i == 0) {
       char *ptr = (char *)malloc(4);
       /* ptr is going out of scope */
}
  /* Memory Leak or Address in Register */

メモリーリーク (mel) エラー

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

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

次に例を示します。

char *ptr;

    ptr = (char *)malloc(1);
    ptr = 0;
/* Memory leak (mel) */