Oracle® Developer Studio 12.5: Discover および Uncover ユーザーズガイド

印刷ビューの終了

更新: 2016 年 6 月
 
 

メモリーアクセスエラーと警告

discover ユーティリティーは、多数のメモリーアクセスエラー、およびエラーである可能性のあるアクセスに関する警告を検出および報告します。

メモリーアクセスエラー

    discover は次のメモリーアクセスエラーを検出します。

  • ABR: 配列境界を越える読み取り (beyond array bounds read)

  • ABW: 配列境界を越える書き込み (beyond array bounds write)

  • BFM: 不正な空きメモリー (bad free memory)

  • BRP: 不正な realloc アドレスパラメータ (bad reallocate address parameter)

  • CGB: 破壊された配列ガードブロック (corrupted array guard block)

  • DFM: メモリーの二重解放 (double freeing memory)

  • FMR: 解放済みメモリーの読み取り (freed memory read)

  • FMW: 解放済みメモリーの書き込み (freed memory write)

  • FRP: 解放済み Realloc パラメータ (freed realloc parameter)

  • IMR: 無効なメモリーの読み取り (invalid memory read)

  • IMW: 無効なメモリーの書き込み (invalid memory write)

  • メモリーリーク

  • OLP: 送り側と受け側の重複 (overlapping source and destination)

  • PIR: 部分的に初期化された読み取り (partially initialized read)

  • SBR: スタックフレームの範囲外からの読み取り (beyond stack frame bounds read)

  • SBW: スタックフレームの範囲外への書き込み (beyond stack frame bounds write)

  • UAR: 割り当てられていないメモリーの読み取り (unallocated memory read)

  • UAW: 割り当てられていないメモリーの書き込み (unallocated memory write)

  • UMR: 初期化されていないメモリーの読み取り (uninitialized memory read)

次のセクションに、これらのエラーの一部を生成する簡単なサンプルプログラムをリストします。

配列境界を越える読み取り (ABR)

例:

  //  ABR: reading memory beyond array bounds at address 0x%1x (%d byte%s)
int *a = (int*) malloc(sizeof(int[5]));
printf("a[5] = %d\n",a[5]);

discover ユーティリティーは、静的な型の ABR エラーも検出します。

    int globalarray[5]; 

   int main(){
     int i, j; 
     for(i = 0; i < 7; i++) { 
       j = globalarray[i-1];   // Reading memory beyond static/global array bounds
     } 
     return 0; 
   }

配列境界を越える書き込み (ABW)

例:

  //  ABW:  writing to memory beyond array bounds
int *a = (int*) malloc(sizeof(int[5]));
a[5] = 5;

discover ユーティリティーは、静的な型の ABW エラーも検出します。

int globalarray[5]; 

   int main(){ 
     int i;
     for(i = 0; i < 7; i++) { 
       globalarray[i-1] = i;   // Writing to memory beyond static/global array bounds
     }
     return 0; 
   }

不正な空きメモリー (BFM)

例:

  //  BFM:  freeing wrong memory block
int *p = (int*) malloc(sizeof(int));
free(p+1);

不正な Realloc アドレスパラメータ (BRP)

例:

  //  BRP:  bad address parameter for realloc 0x%1x
int *p = (int*) realloc(0,sizeof(int));
int *q = (int*) realloc(p+20,sizeof(int[2]));

破損したガードブロック (CGB)

例:

  // CGB: writing past the end of a dynamically allocated array, or being in the "red zone".
    #include <stdio.h>
   #include <stdlib.h>

   int main() {
     int *p = (int *) malloc(sizeof(int)*4);
     *(p+5) = 10; //  Corrupted array guard block detected (only when the code is not annotated)
     free(p);

     return 0;
   }

メモリーの二重解放 (DFM)

例:

  // DFM: double freeing memory
int *p = (int*) malloc(sizeof(int));
free(p);
free(p);'

解放済みメモリーの読み取り (FMR)

例:

  //  FMR: reading from freed memory at address 0x%1x  (%d byte%s)
int *p = (int*) malloc(sizeof(int));
free(p);
printf("p = 0x%h\n",*p);

解放済みメモリーの書き込み (FMW)

例:

  //  FMW: writing to freed memory at address 0x%1x (%d byte%s)
int *p = (int*) malloc(sizeof(int));
free(p);
*p = 1;

解放済み Realloc パラメータ (FRP)

例:

  //  FRP:  freed pointer passed to realloc
int *p = (int*) malloc(sizeof(int));
free(0);
int *q = (int*) realloc(p,sizeof(int[2]));

無効なメモリーの読み取り (IMR)

例:

  //  IMR:  read from invalid memory address
int *p = 0;
int i = *p;   // generates Signal 11...

無効なメモリーの書き込み (IMW)

例:

  //  IMW:  write to invalid memory address
int *p = 0;
*p = 1;       // generates Signal 11...

メモリーリーク

例:

  //  Memory Leak: memory allocated but not freed before exit or escaping from the function
       int foo()
   {
     int *p = (int*) malloc(sizeof(int));
     if (x) {
      p = (int *) malloc(5*sizeof(int));  // will cause a leak of the 1st malloc
     }  
   }                                      // The 2nd malloc leaked here

送り側と受け側の重複 (OLP)

例:

  //  OLP: source and destination overlap
char *s=(char *) malloc(15);
memset(s, 'x', 15);
memcpy(s, s+5, 10);
return 0;

部分的に初期化された読み取り (PIR)

例:

  //  PIR:  accessing partially initialized data
int *p = (int*) malloc(sizeof(int));
*((char*)p) = 'c';
printf("*(p = %d\n",*(p+1)); 

スタック境界を越える読み取り (SBR)

例:

  //  SBR: reading beyond stack frame bounds
int a[2]={0,1};
printf("a[-10]=%d\n",a[-10]);
return 0;

スタック境界を越える書き込み (SBW)

例:

  //  SBW: writing beyond stack frame bounds
int a[2]={0,1)'
a[-10]=2;
return 0;

割り当てられていないメモリーの読み取り (UAR)

例:

  //  UAR" reading from unallocated memory
int *p = (int*) malloc(sizeof(int));
printf("*(p+1) = %d\n",*(p+1));

割り当てられていないメモリーの書き込み (UAW)

例:

  // UMR: accessing uninitialized data from address 0x%1x (A%d byte%s)
int *p = (int*) malloc(sizeof(int));
printf("*p = %d\n",*p);

メモリーアクセスの警告

    discover ユーティリティーは次のメモリーアクセスの警告を報告します。

  • AZS: 0 サイズの割り当て (allocating zero size)

  • SMR: 投機的な非初期化メモリーからの読み取り (speculative uninitialized memory read)

次のセクションにこれらの警告の例を示します。

サイズ 0 の割り当て (AZS)

例:

#include <stdlib>
int main()
{
  int *p = malloc(); // Allocating zero size memory block
}

メモリーリーク (MLK)

考えられる原因: メモリーが割り当てられるが、関数の終了またはエスケープの前に解放されていません。

例:

int foo()
{
 int *p = (int*) malloc(sizeof(int));
 if (x) {
  p = (int *) malloc(5*sizeof(int));  // will cause a leak of the 1st malloc
 }  
}                                     // The 2nd malloc leaked here

投機的なメモリーの読み取り (SMR)

int i;
if (foo(&i) != 0)  /* foo returns nonzero if it has initialized i */
printf("5d\n", i);

コンパイラは、前述のソースに対して次の同等のコードを生成する可能性があります。

int i;
int t1, t2'
t1 = foo(&i);
t2 = i; /* value in i is loaded. So even if t1 is 0, we have uninitialized read due to speculative load */
if (t1 != 0) 
printf("%d\n", t2);