discover 实用程序检测并报告大量内存访问错误,并就可能是错误的访问向您发出警告。
discover 可检测到以下内存访问错误:
ABR:数组越界读
ABW:数组越界写
BFM:释放错误的内存块
BRP:错误的重新分配地址参数
CGB:损坏的数组保护块
DFM:双重释放内存
FMR:读取释放的内存
FMW:写入释放的内存
FRP:释放的重新分配参数
IMR:无效的内存读取
IMW:无效的内存写入
内存泄漏
OLP:重叠源和目标
PIR:部分初始化的读取
SBR:堆栈框架越界读
SBW:堆栈框架越界写
UAR:读取未分配的内存
UAW:写入未分配的内存
UMR:读取未初始化的内存
示例:
// 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: 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: freeing wrong memory block int *p = (int*) malloc(sizeof(int)); free(p+1);
示例:
// 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: 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: double freeing memory int *p = (int*) malloc(sizeof(int)); free(p); free(p);'
示例:
// 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: writing to freed memory at address 0x%1x (%d byte%s) int *p = (int*) malloc(sizeof(int)); free(p); *p = 1;
示例:
// FRP: freed pointer passed to realloc int *p = (int*) malloc(sizeof(int)); free(0); int *q = (int*) realloc(p,sizeof(int[2]));
示例:
// IMR: read from invalid memory address int *p = 0; int i = *p; // generates Signal 11...
示例:
// 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: source and destination overlap char *s=(char *) malloc(15); memset(s, 'x', 15); memcpy(s, s+5, 10); return 0;
示例:
// PIR: accessing partially initialized data
int *p = (int*) malloc(sizeof(int));
*((char*)p) = 'c';
printf("*(p = %d\n",*(p+1));
示例:
// SBR: reading beyond stack frame bounds
int a[2]={0,1};
printf("a[-10]=%d\n",a[-10]);
return 0;
示例:
// SBW: writing beyond stack frame bounds
int a[2]={0,1)'
a[-10]=2;
return 0;
示例:
// UAR" reading from unallocated memory
int *p = (int*) malloc(sizeof(int));
printf("*(p+1) = %d\n",*(p+1));
示例:
// 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:推测性未初始化内存读取
以下部分提供了这些警告的示例。
示例:
#include <stdlib>
int main()
{
int *p = malloc(); // Allocating zero size memory block
}
可能的原因:分配了内存,但是在退出或终止函数之前未释放。
示例:
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
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);