Oracle® Developer Studio 12.5:Discover 和 Uncover 用户指南

退出打印视图

更新时间: 2016 年 6 月
 
 

内存访问错误和警告

discover 实用程序检测并报告大量内存访问错误,并就可能是错误的访问向您发出警告。

内存访问错误

    discover 可检测到以下内存访问错误:

  • ABR:数组越界读

  • ABW:数组越界写

  • BFM:释放错误的内存块

  • BRP:错误的重新分配地址参数

  • CGB:损坏的数组保护块

  • DFM:双重释放内存

  • FMR:读取释放的内存

  • FMW:写入释放的内存

  • FRP:释放的重新分配参数

  • IMR:无效的内存读取

  • IMW:无效的内存写入

  • 内存泄漏

  • OLP:重叠源和目标

  • PIR:部分初始化的读取

  • SBR:堆栈框架越界读

  • SBW:堆栈框架越界写

  • UAR:读取未分配的内存

  • UAW:写入未分配的内存

  • UMR:读取未初始化的内存

以下各节列出了一些将生成其中部分错误的简单样例程序。

数组越界读 (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);

错误的重新分配地址参数 (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;

释放的重新分配参数 (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:分配零大小

  • SMR:推测性未初始化内存读取

以下部分提供了这些警告的示例。

分配零大小 (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);