Reimplement malloc/free debugging that includes the offending file:line

info.  This turned out to be rather useful on ia64 for tracking down
malloc/free problems.
Detect duplicate free()'s - otherwise these show up as a guard1 failure
and it looks like corruption instead of something simple like a second
free() where there shouldn't be.
Deal with libz using libc headers and not seeing the malloc/free stuff that
we provide in libstand.  Do similar nastiness to what is done for bzlib.

Tested on: i386, ia64 (compile, run)
This commit is contained in:
Peter Wemm 2002-07-20 04:18:20 +00:00
parent 683eac8dbb
commit 21a7fd75c3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=100394
5 changed files with 72 additions and 39 deletions

View File

@ -12,7 +12,8 @@ NOPIC= YES
INCS= stand.h
MAN= libstand.3
CFLAGS+= -ffreestanding
CFLAGS+= -ffreestanding -Wformat
CFLAGS+= -I${.CURDIR}
.if ${MACHINE_ARCH} == "alpha"
CFLAGS+= -mno-fp-regs
@ -25,7 +26,7 @@ CFLAGS+= -msoft-float
.endif
# standalone components and stuff we have modified locally
SRCS+= __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
SRCS+= zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \
sbrk.c twiddle.c zalloc.c zalloc_malloc.c
@ -132,9 +133,22 @@ _${file}: ${file}
# decompression functionality from libz
.PATH: ${.CURDIR}/../libz
CFLAGS+=-DHAVE_MEMCPY
SRCS+= adler32.c crc32.c infblock.c infcodes.c inffast.c inflate.c \
inftrees.c infutil.c zutil.c
CFLAGS+=-DHAVE_MEMCPY -I${.CURDIR}/../libz
SRCS+= adler32.c crc32.c _infblock.c _infcodes.c _inffast.c _inflate.c \
_inftrees.c _infutil.c _zutil.c _zutil.h
# aargh
.for file in zutil.h
CLEANFILES+= _${file} _${file}.orig
_${file}: ${file} ${file}.diff
patch -s -b .orig -o ${.TARGET} < ${.ALLSRC:M*.diff} ${.ALLSRC:M*.[ch]}
.endfor
.for file in infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c zutil.c
_${file}: ${file}
sed "s|zutil\.h|_zutil.h|" ${.ALLSRC} > ${.TARGET}
.endfor
# io routines
SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \

View File

@ -391,26 +391,19 @@ extern uint16_t ntohs(uint16_t);
#define ntohs(x) __ntohs(x)
#endif
#if 0
static inline void *
malloc_debug(size_t size, const char *file, int line)
{
void *p;
printf("%s:%d malloc(%ld)", file, line, size);
p = malloc(size);
printf("=%p\n", p);
return p;
}
static inline void
free_debug(void *p, const char *file, int line)
{
printf("%s:%d free(%p)\n", file, line, p);
free(p);
}
#define malloc(x) malloc_debug(x, __FILE__, __LINE__)
#define free(x) free_debug(x, __FILE__, __LINE__)
void *Malloc(size_t, const char *, int);
void *Calloc(size_t, size_t, const char *, int);
void *Realloc(void *, size_t, const char *, int);
void Free(void *, const char *, int);
#if 1
#define malloc(x) Malloc(x, __FILE__, __LINE__)
#define calloc(x, y) Calloc(x, y, __FILE__, __LINE__)
#define free(x) Free(x, __FILE__, __LINE__)
#define realloc(x, y) Realloc(x, y, __FILE__, __LINE__)
#else
#define malloc(x) Malloc(x, NULL 0)
#define calloc(x, y) Calloc(x, y, NULL, 0)
#define free(x) Free(x, NULL, 0)
#define realloc(x, y) Realloc(x, y, NULL, 0)
#endif

View File

@ -96,6 +96,7 @@ typedef struct Guard {
#define MATYPE long double
#define MALLOCALIGN ((sizeof(MATYPE) > sizeof(Guard)) ? sizeof(MATYPE) : sizeof(Guard))
#define GAMAGIC 0x55FF44FD
#define GAFREE 0x5F54F4DF
#include "zalloc_protos.h"

View File

@ -60,7 +60,7 @@ free_region(void *start, void *end)
#endif
void *
malloc(size_t bytes)
Malloc(size_t bytes, const char *file, int line)
{
Guard *res;
@ -94,21 +94,31 @@ malloc(size_t bytes)
}
void
free(void *ptr)
Free(void *ptr, const char *file, int line)
{
size_t bytes;
if (ptr != NULL) {
Guard *res = (void *)((char *)ptr - MALLOCALIGN);
if (file == NULL)
file = "unknown";
#ifdef USEGUARD
if (res->ga_Magic == GAFREE) {
printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line);
return;
}
if (res->ga_Magic != GAMAGIC)
panic("free: guard1 fail @ %p", ptr);
res->ga_Magic = -1;
panic("free: guard1 fail @ %p from %s:%p", ptr, file, line);
res->ga_Magic = GAFREE;
#endif
#ifdef USEENDGUARD
if (*((char *)res + res->ga_Bytes - 1) == -1) {
printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line);
return;
}
if (*((char *)res + res->ga_Bytes - 1) != -2)
panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN);
panic("free: guard2 fail @ %p + %d from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line);
*((char *)res + res->ga_Bytes - 1) = -1;
#endif
@ -122,12 +132,12 @@ free(void *ptr)
void *
calloc(size_t n1, size_t n2)
Calloc(size_t n1, size_t n2, const char *file, int line)
{
iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
void *res;
if ((res = malloc(bytes)) != NULL) {
if ((res = Malloc(bytes, file, line)) != NULL) {
bzero(res, bytes);
#ifdef DMALLOCDEBUG
if (++MallocCount > MallocMax)
@ -144,19 +154,19 @@ calloc(size_t n1, size_t n2)
*/
void *
realloc(void *ptr, size_t size)
Realloc(void *ptr, size_t size, const char *file, int line)
{
void *res;
size_t old;
if ((res = malloc(size)) != NULL) {
if ((res = Malloc(size, file, line)) != NULL) {
if (ptr) {
old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
if (old < size)
bcopy(ptr, res, old);
else
bcopy(ptr, res, size);
free(ptr);
Free(ptr, file, line);
} else {
#ifdef DMALLOCDEBUG
if (++MallocCount > MallocMax)
@ -174,12 +184,12 @@ realloc(void *ptr, size_t size)
}
void *
reallocf(void *ptr, size_t size)
Reallocf(void *ptr, size_t size, const char *file, int line)
{
void *res;
if ((res = realloc(ptr, size)) == NULL)
free(ptr);
if ((res = Realloc(ptr, size, file, line)) == NULL)
Free(ptr, file, line);
return(res);
}

15
lib/libstand/zutil.h.diff Normal file
View File

@ -0,0 +1,15 @@
$FreeBSD$
--- zutil.h Fri Jun 28 23:58:21 2002
+++ zutil.h Fri Jun 28 23:56:24 2002
@@ -15,11 +15,7 @@
#include "zlib.h"
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
+#include "stand.h"
#ifdef NO_ERRNO_H
extern int errno;