The discover utility detects and reports many memory access errors, as well as warning you about accesses that might be errors.
discover detects the following memory access errors:
ABR: beyond array bounds read
ABW: beyond array bounds write
BFM: bad free memory
BRP: bad reallocate address parameter
CGB: corrupted array guard block
DFM: double freeing memory
FMR: freed memory read
FMW: freed memory write
FRP: freed realloc parameter
IMR: invalid memory read
IMW: invalid memory write
Memory leak
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
The following sections list some simple sample programs that will produce some of these errors.
Example:
// 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]);
The discover utility also detects static-type ABR errors.
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; }
Example:
// ABW: writing to memory beyond array bounds int *a = (int*) malloc(sizeof(int[5])); a[5] = 5;
The discover utility also detects static-type ABW errors.
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; }
Example:
// BFM: freeing wrong memory block int *p = (int*) malloc(sizeof(int)); free(p+1);
Example:
// BRP: bad address parameter for realloc 0x%1x int *p = (int*) realloc(0,sizeof(int)); int *q = (int*) realloc(p+20,sizeof(int[2]));
Example:
// 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; }
Example:
// DFM: double freeing memory int *p = (int*) malloc(sizeof(int)); free(p); free(p);'
Example:
// 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);
Example:
// FMW: writing to freed memory at address 0x%1x (%d byte%s) int *p = (int*) malloc(sizeof(int)); free(p); *p = 1;
Example:
// FRP: freed pointer passed to realloc int *p = (int*) malloc(sizeof(int)); free(0); int *q = (int*) realloc(p,sizeof(int[2]));
Example:
// IMR: read from invalid memory address int *p = 0; int i = *p; // generates Signal 11...
Example:
// IMW: write to invalid memory address int *p = 0; *p = 1; // generates Signal 11...
Example:
// 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
Example:
// OLP: source and destination overlap char *s=(char *) malloc(15); memset(s, 'x', 15); memcpy(s, s+5, 10); return 0;
Example:
// PIR: accessing partially initialized data int *p = (int*) malloc(sizeof(int)); *((char*)p) = 'c'; printf("*(p = %d\n",*(p+1));
Example:
// SBR: reading beyond stack frame bounds int a[2]={0,1}; printf("a[-10]=%d\n",a[-10]); return 0;
Example:
// SBW: writing beyond stack frame bounds int a[2]={0,1)' a[-10]=2; return 0;
Example:
// UAR" reading from unallocated memory int *p = (int*) malloc(sizeof(int)); printf("*(p+1) = %d\n",*(p+1));
Example:
// UMR: accessing uninitialized data from address 0x%1x (A%d byte%s) int *p = (int*) malloc(sizeof(int)); printf("*p = %d\n",*p);
The discover utility reports the following memory access warnings:
AZS: allocating zero size
SMR: speculative uninitialized memory read
The following sections gives examples of these warnings.
Example:
#include <stdlib> int main() { int *p = malloc(); // Allocating zero size memory block }
Possible causes: Memory is allocated but not freed before exit or escaping from the function.
Example:
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);
The compiler might generate the following equivalent code for the above source:
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);