Pointer validation code

DanKarron at UCBVAX.BERKELEY.EDU DanKarron at UCBVAX.BERKELEY.EDU
Mon Feb 4 09:10:12 AEST 1991


Appended below is some code I use for validating pointers. It depends
on knowing the layout of user process memory text, heap and stack boundries.

I am including this with the hope that if you have a technique you use to
debug bad pointers you will send it to me or post it too.

If you want to use the code below in your buggy application, you need to
do two things: 1) include the .h file in your application code, and 
2) link in the .o file from the .c file below.

Setting setenv DEBUG_HEAP will produce too much output, but if the
Free detects a bad pointer (which is why I did this) it will turn on
debug output for all succeeding memory allocations calls and make lots of
output.

These bugs are especially pernicious, because the structure of the heap
can be corrupted with no symptoms at all, or for many malloc calls before
you get a error. A bad pointer to free will subtly corrup the heap without
any immediate symptoms. 

If you have a a favorite technique you use to track pointer bugs, 
I would appreciate hearing how you do it ! 

Cheers!

dan.
--------------------------MemoryDeBug.h-------------------------------------

#define calloc(a,b) Calloc(a,b,__FILE__,__LINE__)
#define malloc(a) Malloc(a,__FILE__,__LINE__)
#define free(a) Free(a,__FILE__,__LINE__)
#define strdup(a) Strdup(a,__FILE__,__LINE__)

extern void *Calloc(size_t nelem, size_t elsize,char *file,int line);
extern void *Malloc(size_t elsize,char *file,int line);
void Free(void *freeme,char *file,int line);
extern char *Strdup(char *dup_me,char *file,int line);
--------------------------MemoryDeBug.c-------------------------------------
#include "stdio.h"
#include "malloc.h"
#include "string.h"
#include "setjmp.h"

#define DEBUG_ENVIRON "DEBUG_HEAP"
#define STACK_POINTER (setjmp(jumped_buffer),(void *)jumped_buffer[JB_SP] )
#define STACK_BASE (void *)0x7ffff000

void *sbrk (int incr); /* stbrk(0) returns the top of the heap */

extern _ftext; /* beginning of text segment     */
extern etext;  /* one after end of text segment */

extern _fdata; /* beginning of the static initalized data segment */
extern edata;  /* one after end of static initalized data         */

extern _fbss;  /* beginning of uninitalized static data , at edata  */
extern end;    /* one after end of init data, and beginning of heap */

static int Error_Happened;


void *Calloc(size_t nelem, size_t elsize,char *file,int line)
{
void *ptr;
if(getenv(DEBUG_ENVIRON)||Error_Happened)
	printf("Calloc(%d,%d) called at %s,%d ",nelem,elsize,file,line);
ptr=calloc(nelem,elsize);
if(!ptr)
	{
	fprintf(stderr,"Calloc failed, no memory being returned\n");
	Error_Happened=1;
	}
if(getenv(DEBUG_ENVIRON)||Error_Happened)
	printf(" returning %#x to %#x\n",ptr,(long int)ptr+(nelem*elsize));
return ptr;
}
/***************************************************************************/
void *Malloc(size_t elsize,char *file,int line)
{
void *ptr;
if(getenv(DEBUG_ENVIRON)||Error_Happened)
	printf("Calloc(%d) called at %s,%d ",elsize,file,line);
ptr=malloc(elsize);
if(!ptr)
	{
	fprintf(stderr,"Malloc failed, no memory being returned\n");
	Error_Happened=1;
	}
if(getenv(DEBUG_ENVIRON)||Error_Happened)
	printf(" returning %#x to %#x\n",ptr,(long int)ptr+(elsize));
return ptr;
}
/***************************************************************************/
void *Free(void *ptr,char *file,int line)
{
jmp_buf jumped_buffer;

if(ptr == (void *)0)
	{
	fprintf(stderr,"ZERO POINTER to Free\n");
	Error_Happened=1;
	}
else if(ptr< &_ftext)
	fprintf(stderr,"BAD POINTER to Free, below beginning of text, %#x < %#x\n",
		ptr,&_ftext),Error_Happened=1;
else if(ptr >= &_ftext && ptr < &etext )
	fprintf(stderr,"BAD POIINTER to Free, in program text segment, %#x >= %#x < %#x\n",
		&_ftext,ptr,&etext),Error_Happened=1;
else if(ptr >= &etext && ptr < &_fdata )
	fprintf(stderr,"BAD POINTER to Free, between program text and data, %#x >= %#x < %#x\n",
		&etext, ptr, &_fdata),Error_Happened=1;
else if(ptr >= &_fdata && ptr < &_fbss)
	fprintf(stderr,"BAD POINTER to Free, in static initalized text area, %#x >= %#x < %#x\n",
		&_fdata, ptr, &_fbss),Error_Happened=1;
else if(ptr >= &_fbss && ptr < &end)
	fprintf(stderr,"BAD POINTER to Free, in static uninitalized data area, %#x >= %#x < %#x\n",
		&_fbss,ptr,&end),Error_Happened=1;
else if( ptr >= &end && ptr < sbrk(0) )
	{
	if(getenv(DEBUG_ENVIRON)||Error_Happened)
		printf("Free(%#x) at %s,%d\n",ptr,file,line);
	free(ptr);
	}
else if(ptr >= sbrk(0) && ptr < STACK_POINTER )
	fprintf(stderr,"BAD POINTER to Free, beyond top of heap, %#x >= %#x\n",
		sbrk(0),ptr,STACK_POINTER),Error_Happened=1;
else if(ptr >= STACK_POINTER && ptr < STACK_BASE )
	fprintf(stderr,"BAD POINTER to Free, in stack, %#x >= %#x < %#x\n",
		STACK_POINTER,ptr,STACK_BASE),Error_Happened=1;
else if(ptr >= STACK_BASE)
	fprintf(stderr,"BAD POINTER to Free, beyond top of stack base, %#x >= %#x\n",
		ptr, STACK_BASE),Error_Happened=1;
else ;
}
/**************************************************************************/
char *Strdup(char *dup_me,char *file,int line)
{
char *string;
int string_length;
int i;
if(getenv(DEBUG_ENVIRON)||Error_Happened)
	printf("Strdup(%s,%d) at %s,%d",dup_me,strlen(dup_me),file,line);
for(i=0;dup_me[i]!=NULL;i++);
string_length = i+1;
string=calloc(string_length,sizeof(char));
for(i=0;i<string_length;i++)
	string[i]=dup_me[i];
if(getenv(DEBUG_ENVIRON)||Error_Happened)
	printf(" with %#x\n",string);
return string;
}
+-----------------------------------------------------------------------------+
| karron at nyu.edu (E-mail alias that will always find me)                      |
| Fax: 212 263 7190           *           Dan Karron, Research Associate      |
| . . . . . . . . . . . . . . *           New York University Medical Center  |
| 560 First Avenue           \*\    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 263 5210               \***\_________________________________________ |
| Main machine: karron.med.nyu.edu (128.122.135.3) IRIS 85GT                  |
+-----------------------------------------------------------------------------+

NOTE PHONE NUMBER CHANGE: The Med Ctr has changed from 340 to 263 exchange.



More information about the Comp.sys.sgi mailing list