Paranoid malloc()s?

Andrew Valencia vandys at sequent.com
Fri Jun 14 01:10:52 AEST 1991


ss7m+ at 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 at 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);
}



More information about the Alt.sources mailing list