Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!ucbvax!UCBVAX.BERKELEY.EDU!"Dan Karron From: Dan Karron@UCBVAX.BERKELEY.EDU Newsgroups: comp.sys.sgi Subject: Pointer validation code Message-ID: <9102032210.AA26607@karron.med.nyu.edu> Date: 3 Feb 91 22:10:12 GMT Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: karron@cmcl2.nyu.edu Organization: The Internet Lines: 163 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 (212) 397 9330 | | New York, New York 10016 \**\ <2> 10896 <3> | | (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.