Xref: utzoo alt.sources:3886 alt.sources.d:1874 Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!sequent!muncher.sequent.com!news From: vandys@sequent.com (Andrew Valencia) Newsgroups: alt.sources,alt.sources.d Subject: Re: Paranoid malloc()s? Message-ID: <1991Jun13.151052.27322@sequent.com> Date: 13 Jun 91 15:10:52 GMT References: Sender: news@sequent.com (News on Muncher) Organization: Sequent Computer Systems, Inc. Lines: 130 ss7m+@andrew.cmu.edu (Steven M. Stadnicki) writes: >Does anyone know where any librarys of this nature can be found? I've got a >lurking memory leak somewhere in the code I'm working with, and was hoping for >something that'll match mallocs and frees and tell me what I'm missing... Well, I don't have quite that. But here's my malloc/free package for catching abuse of allocated and use of free'ed or realloc'd memory. Use at your own risk! It uses mmap() and munmap(), so you'll need a later vintage System V or BSD. Andy Valencia vandys@sequent.com /* * A brute-force malloc() interface which attempts to back up each * allocated piece of data against an invalid page, so that references * off the end cause a segmentation violation. */ extern char *sbrk(); static unsigned long pagesize; char * malloc(size) unsigned size; { static int setup = 0; unsigned long l; char *p; /* * Adjust up so we can slip a "size" word up front. Also pad by an * extra longword because the C library expects strings to not fall * into an invalid page within one word from their end. */ size += sizeof(unsigned) + sizeof(long); /* * Round size to longword boundary */ if (size & (sizeof(long)-1)) { size += (sizeof(long) - (size & (sizeof(long)-1))); } /* * Get some overhead over with once */ if (!setup) { pagesize = getpagesize(); setup = 1; } /* * Make sure break is on a page boundry */ l = (unsigned long)sbrk(0); l &= (pagesize-1); l = pagesize - l; (void)sbrk((int)l); /* * Now allocate one page beyond size needed to hold data */ l = (size + (pagesize-1)) & ~(pagesize-1); l = pagesize * (l/pagesize + 1); p = sbrk((int)l); /* * Out of memory--foo */ if (p == 0) return(p); /* * Unvirtualize last page, return pointer to data backed * up against top of remaining memory. */ p += l; (void) munmap(p - pagesize, pagesize); /* * Adjust data to back up against the end of the memory */ p -= (pagesize + size); *(unsigned *)p = size; return (p+sizeof(unsigned)); } /* * Free memory. Unvirtualize and thus catch stale-memory cheaters. */ void free(ptr) char *ptr; { unsigned long l; int npages; /* * Figure out how big a chunk we're done with */ ptr -= sizeof(unsigned); l = *(unsigned *)ptr; l = (l + (pagesize-1)) & ~(pagesize-1); npages = l/pagesize; /* * Get base of memory, unmap it */ l = (unsigned long)ptr; l &= ~(pagesize-1); (void) munmap(l, npages*pagesize); } char * realloc(ptr, size) char *ptr; unsigned size; { register char *p; unsigned osize; if ((p = malloc(size)) == 0) return(p); osize = *(unsigned *)(ptr - sizeof(unsigned)); memcpy(p, ptr, osize); free(ptr); return(p); }