mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Update from main archive 961219
Thu Dec 19 23:28:33 1996 Ulrich Drepper <drepper@cygnus.com> * resolv/resolv.h: Update from BIND 4.9.5-P1. * resolv/res_comp.c: Likewise. * resolv/res_debug.c: Likewise. * resolv/Banner: Update version number. Thu Dec 19 20:58:53 1996 Ulrich Drepper <drepper@cygnus.com> * elf/dlfcn.h: Add extern "C" wrapper. * io/utime.h: Don't define NULL since this isn't allowed in POSIX. * io/sys/stat.h: Declare `lstat' only if __USE_BSD || __USE_XOPEN_EXTENDED. * locale/locale.h: Define NULL. * math/math.c: Don't include <errno.h> to define math errors. * stdlib/stdlib.h: Likewise. * posix/unistd.h: Don't declare environ. * posix/sys/utsname.h (struct utsname): Declare member domainname as __domainname is !__USE_GNU. * signal/signal.h: Declare size_t only if __USE_BSD || __USE_XOPEN_EXTENDED. * stdio/stdio.h: Don't declare cuserid when __USE_POSIX, but instead when __USE_XOPEN. * string/string.h: Define strndup only if __USE_GNU. * sysdeps/unix/sysv/linux/clock.c: New file. * sysdeps/unix/sysv/linux/timebits.h: Define CLOCKS_PER_SEC as 1000000 per X/Open standard. * features.h: Add code to recognize _POSIX_C_SOURCE value 199309. Define __USE_POSIX199309. * posix/unistd.h: Declare fdatasync only if __USE_POSIX199309. * time/time.c: Declare nanosleep only if __USE_POSIX199309. Patches by Rdiger Helsch <rh@unifix.de>. * locale/locale.h: Add declaration of newlocale and freelocale. * new-malloc/Makefile (distibute): Add mtrace.awk. (dist-routines): Add mcheck and mtrace. (install-lib, non-lib.a): Define as libmcheck.a. * new-malloc/malloc.h: Add declaration of __malloc_initialized. * new-malloc/mcheck.c: New file. * new-malloc/mcheck.h: New file. * new-malloc/mtrace.c: New file. * new-malloc/mtrace.awk: New file. * posix/unistd.h: Correct prototype for usleep. * sysdeps/unix/bsd/usleep.c: De-ANSI-declfy. Correct return type. * sysdeps/unix/sysv/linux/usleep.c: Real implementation based on nanosleep. * signal/signal.h: Change protoype of __sigpause to take two arguments. Remove prototype for sigpause. Add two different macros named sigpause selected when __USE_BSD or __USE_XOPEN are defined. This is necessary since the old BSD definition of theis function collides with the X/Open definition. * sysdeps/posix/sigpause.c: Change function definition to also fit X/Open definition. * sysdeps/libm-i387/e_exp.S: Make sure stack is empty when the function is left. * sysdeps/libm-i387/e_expl.S: Likewise. Patch by HJ Lu. 1996-12-17 Paul Eggert <eggert@twinsun.com> * many, many files: Spelling corrections. * catgets/catgetsinfo.h (mmapped): Renamed from mmaped (in struct catalog_info.status). * mach/err_kern.sub (err_codes_unix), string/stratcliff.c (main): Fix spelling in message. * po/libc.pot: Fix spelling in message for `zic'; this anticipates a fix in the tzcode distribution. Wed Dec 18 15:48:02 1996 Ulrich Drepper <drepper@cygnus.com> * time/strftime.c: Implement ^ flag to cause output be converted to use upper case characters. * time/zic.c: Update from ADO tzcode1996n. Wed Dec 18 14:29:24 1996 Erik Naggum <erik@naggum.no> * time/strftime.c (add): Don't change global `i' until all is over. Define NULL is not already defined. Tue Dec 17 09:49:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * libio/iovsprintf.c (_IO_vsprintf): Change `&sf' to `&sf._sbf._f' to avoid the need for a cast. * libio/iovsscanf.c (_IO_vsscanf): Likewise. * sunrpc/rpc/xdr.h: Add prototype for xdr_free.
This commit is contained in:
@ -27,15 +27,27 @@ dist-headers := malloc.h
|
||||
headers := $(dist-headers) obstack.h
|
||||
tests := mallocbug
|
||||
|
||||
distribute = thread-m.h
|
||||
distribute = thread-m.h mtrace.awk
|
||||
|
||||
# Things which get pasted together into gmalloc.c.
|
||||
gmalloc-routines := malloc morecore
|
||||
# Things to include in the standalone distribution.
|
||||
dist-routines = $(gmalloc-routines)
|
||||
dist-routines = $(gmalloc-routines) mcheck mtrace
|
||||
routines = $(dist-routines) obstack
|
||||
|
||||
install-lib := libmcheck.a
|
||||
non-lib.a := libmcheck.a
|
||||
|
||||
# These should be removed by `make clean'.
|
||||
extra-objs = mcheck-init.o libmcheck.a
|
||||
|
||||
include ../Rules
|
||||
|
||||
$(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
|
||||
-rm -f $@
|
||||
ln $< $@
|
||||
|
||||
lib: $(objpfx)libmcheck.a
|
||||
|
||||
|
||||
CPPFLAGS-malloc.o += -DMALLOC_DEBUG
|
||||
CFLAGS-obstack.c = -Wno-strict-prototypes
|
||||
|
@ -140,7 +140,7 @@
|
||||
|
||||
Maximum overhead wastage per allocated chunk: normally 15 bytes
|
||||
|
||||
Alignnment demands, plus the minimum allocatable size restriction
|
||||
Alignment demands, plus the minimum allocatable size restriction
|
||||
make the normal worst-case wastage 15 bytes (i.e., up to 15
|
||||
more bytes will be allocated than were requested in malloc), with
|
||||
two exceptions:
|
||||
@ -343,7 +343,7 @@ extern "C" {
|
||||
checking is fairly extensive, and will slow down execution
|
||||
noticeably. Calling malloc_stats or mallinfo with MALLOC_DEBUG set will
|
||||
attempt to check every non-mmapped allocated and free chunk in the
|
||||
course of computing the summmaries. (By nature, mmapped regions
|
||||
course of computing the summaries. (By nature, mmapped regions
|
||||
cannot be checked very much automatically.)
|
||||
|
||||
Setting MALLOC_DEBUG may also be helpful if you are trying to modify
|
||||
@ -999,7 +999,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
the malloc code, but "mem" is the pointer that is returned to the
|
||||
user. "Nextchunk" is the beginning of the next contiguous chunk.
|
||||
|
||||
Chunks always begin on even word boundries, so the mem portion
|
||||
Chunks always begin on even word boundaries, so the mem portion
|
||||
(which is returned to the user) is also on an even word boundary, and
|
||||
thus double-word aligned.
|
||||
|
||||
@ -1144,7 +1144,7 @@ typedef struct _arena {
|
||||
} arena;
|
||||
|
||||
|
||||
/* A heap is a single contiguous memory region holding (coalescable)
|
||||
/* A heap is a single contiguous memory region holding (coalesceable)
|
||||
malloc_chunks. It is allocated with mmap() and always starts at an
|
||||
address aligned to HEAP_MAX_SIZE. Not used unless compiling for
|
||||
multiple threads. */
|
||||
@ -1489,6 +1489,8 @@ static unsigned long max_mmapped_mem = 0;
|
||||
|
||||
|
||||
|
||||
/* Already initialized? */
|
||||
int __malloc_initialized;
|
||||
|
||||
|
||||
/* Initialization routine. */
|
||||
@ -1504,13 +1506,12 @@ void
|
||||
ptmalloc_init __MALLOC_P((void))
|
||||
#endif
|
||||
{
|
||||
static int first = 1;
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
const char* s;
|
||||
#endif
|
||||
|
||||
if(!first) return;
|
||||
first = 0;
|
||||
if(__malloc_initialized) return;
|
||||
__malloc_initialized = 1;
|
||||
#if defined(_LIBC)
|
||||
/* Initialize the pthreads interface. */
|
||||
if (__pthread_initialize != NULL)
|
||||
@ -3589,7 +3590,7 @@ dump_heap(heap) heap_info *heap;
|
||||
|
||||
malloc_stats:
|
||||
|
||||
For all arenas seperately and in total, prints on stderr the
|
||||
For all arenas separately and in total, prints on stderr the
|
||||
amount of space obtained from the system, and the current number
|
||||
of bytes allocated via malloc (or realloc, etc) but not yet
|
||||
freed. (Note that this is the number of bytes allocated, not the
|
||||
@ -3964,10 +3965,10 @@ History:
|
||||
Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
|
||||
* Use last_remainder in more cases.
|
||||
* Pack bins using idea from colin@nyx10.cs.du.edu
|
||||
* Use ordered bins instead of best-fit threshhold
|
||||
* Use ordered bins instead of best-fit threshold
|
||||
* Eliminate block-local decls to simplify tracing and debugging.
|
||||
* Support another case of realloc via move into top
|
||||
* Fix error occuring when initial sbrk_base not word-aligned.
|
||||
* Fix error occurring when initial sbrk_base not word-aligned.
|
||||
* Rely on page size for units instead of SBRK_UNIT to
|
||||
avoid surprises about sbrk alignment conventions.
|
||||
* Add mallinfo, mallopt. Thanks to Raymond Nijssen
|
||||
|
@ -73,6 +73,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Nonzero if the malloc is already initialized. */
|
||||
extern int __malloc_initialized;
|
||||
|
||||
/* Initialize global configuration. Not needed with GNU libc. */
|
||||
#ifndef __GLIBC__
|
||||
extern void ptmalloc_init __MALLOC_P ((void));
|
||||
|
30
malloc/mcheck-init.c
Normal file
30
malloc/mcheck-init.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* The object of this file should be installed as libmcheck.a,
|
||||
so one can do -lmcheck to turn on mcheck. */
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
static void
|
||||
turn_on_mcheck __P ((void))
|
||||
{
|
||||
mcheck (NULL);
|
||||
}
|
||||
|
||||
void (*__malloc_initialize_hook) __P ((void)) = turn_on_mcheck;
|
232
malloc/mcheck.c
Normal file
232
malloc/mcheck.c
Normal file
@ -0,0 +1,232 @@
|
||||
/* Standard debugging hooks for `malloc'.
|
||||
Copyright (C) 1990,91,92,93,94,95,96 Free Software Foundation, Inc.
|
||||
Written May 1989 by Mike Haertel.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
The author may be reached (Email) at the address mike@ai.mit.edu,
|
||||
or (US mail) as Mike Haertel c/o Free Software Foundation. */
|
||||
|
||||
#ifndef _MALLOC_INTERNAL
|
||||
#define _MALLOC_INTERNAL
|
||||
#include <malloc.h>
|
||||
#include <mcheck.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* Old hook values. */
|
||||
static void (*old_free_hook) __P ((__ptr_t ptr));
|
||||
static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size));
|
||||
static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
|
||||
|
||||
/* Function to call when something awful happens. */
|
||||
static void (*abortfunc) __P ((enum mcheck_status));
|
||||
|
||||
/* Arbitrary magical numbers. */
|
||||
#define MAGICWORD 0xfedabeeb
|
||||
#define MAGICFREE 0xd8675309
|
||||
#define MAGICBYTE ((char) 0xd7)
|
||||
#define MALLOCFLOOD ((char) 0x93)
|
||||
#define FREEFLOOD ((char) 0x95)
|
||||
|
||||
struct hdr
|
||||
{
|
||||
__malloc_size_t size; /* Exact size requested by user. */
|
||||
unsigned long int magic; /* Magic number to check header integrity. */
|
||||
};
|
||||
|
||||
#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
|
||||
#define flood memset
|
||||
#else
|
||||
static void flood __P ((__ptr_t, int, __malloc_size_t));
|
||||
static void
|
||||
flood (ptr, val, size)
|
||||
__ptr_t ptr;
|
||||
int val;
|
||||
__malloc_size_t size;
|
||||
{
|
||||
char *cp = ptr;
|
||||
while (size--)
|
||||
*cp++ = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static enum mcheck_status checkhdr __P ((const struct hdr *));
|
||||
static enum mcheck_status
|
||||
checkhdr (hdr)
|
||||
const struct hdr *hdr;
|
||||
{
|
||||
enum mcheck_status status;
|
||||
switch (hdr->magic)
|
||||
{
|
||||
default:
|
||||
status = MCHECK_HEAD;
|
||||
break;
|
||||
case MAGICFREE:
|
||||
status = MCHECK_FREE;
|
||||
break;
|
||||
case MAGICWORD:
|
||||
if (((char *) &hdr[1])[hdr->size] != MAGICBYTE)
|
||||
status = MCHECK_TAIL;
|
||||
else
|
||||
status = MCHECK_OK;
|
||||
break;
|
||||
}
|
||||
if (status != MCHECK_OK)
|
||||
(*abortfunc) (status);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void freehook __P ((__ptr_t));
|
||||
static void
|
||||
freehook (ptr)
|
||||
__ptr_t ptr;
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
struct hdr *hdr = ((struct hdr *) ptr) - 1;
|
||||
checkhdr (hdr);
|
||||
hdr->magic = MAGICFREE;
|
||||
flood (ptr, FREEFLOOD, hdr->size);
|
||||
ptr = (__ptr_t) hdr;
|
||||
}
|
||||
__free_hook = old_free_hook;
|
||||
free (ptr);
|
||||
__free_hook = freehook;
|
||||
}
|
||||
|
||||
static __ptr_t mallochook __P ((__malloc_size_t));
|
||||
static __ptr_t
|
||||
mallochook (size)
|
||||
__malloc_size_t size;
|
||||
{
|
||||
struct hdr *hdr;
|
||||
|
||||
__malloc_hook = old_malloc_hook;
|
||||
hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
|
||||
__malloc_hook = mallochook;
|
||||
if (hdr == NULL)
|
||||
return NULL;
|
||||
|
||||
hdr->size = size;
|
||||
hdr->magic = MAGICWORD;
|
||||
((char *) &hdr[1])[size] = MAGICBYTE;
|
||||
flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
|
||||
return (__ptr_t) (hdr + 1);
|
||||
}
|
||||
|
||||
static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t));
|
||||
static __ptr_t
|
||||
reallochook (ptr, size)
|
||||
__ptr_t ptr;
|
||||
__malloc_size_t size;
|
||||
{
|
||||
struct hdr *hdr;
|
||||
__malloc_size_t osize;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
hdr = ((struct hdr *) ptr) - 1;
|
||||
osize = hdr->size;
|
||||
|
||||
checkhdr (hdr);
|
||||
if (size < osize)
|
||||
flood ((char *) ptr + size, FREEFLOOD, osize - size);
|
||||
}
|
||||
else
|
||||
{
|
||||
osize = 0;
|
||||
hdr = NULL;
|
||||
}
|
||||
__free_hook = old_free_hook;
|
||||
__malloc_hook = old_malloc_hook;
|
||||
__realloc_hook = old_realloc_hook;
|
||||
hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1);
|
||||
__free_hook = freehook;
|
||||
__malloc_hook = mallochook;
|
||||
__realloc_hook = reallochook;
|
||||
if (hdr == NULL)
|
||||
return NULL;
|
||||
|
||||
hdr->size = size;
|
||||
hdr->magic = MAGICWORD;
|
||||
((char *) &hdr[1])[size] = MAGICBYTE;
|
||||
if (size > osize)
|
||||
flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
|
||||
return (__ptr_t) (hdr + 1);
|
||||
}
|
||||
|
||||
static void mabort __P ((enum mcheck_status status));
|
||||
static void
|
||||
mabort (status)
|
||||
enum mcheck_status status;
|
||||
{
|
||||
const char *msg;
|
||||
switch (status)
|
||||
{
|
||||
case MCHECK_OK:
|
||||
msg = _("memory is consistent, library is buggy");
|
||||
break;
|
||||
case MCHECK_HEAD:
|
||||
msg = _("memory clobbered before allocated block");
|
||||
break;
|
||||
case MCHECK_TAIL:
|
||||
msg = _("memory clobbered past end of allocated block");
|
||||
break;
|
||||
case MCHECK_FREE:
|
||||
msg = _("block freed twice");
|
||||
break;
|
||||
default:
|
||||
msg = _("bogus mcheck_status, library is buggy");
|
||||
break;
|
||||
}
|
||||
#ifdef _LIBC
|
||||
__libc_fatal (msg);
|
||||
#else
|
||||
fprintf (stderr, "mcheck: %s\n", msg);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mcheck_used = 0;
|
||||
|
||||
int
|
||||
mcheck (func)
|
||||
void (*func) __P ((enum mcheck_status));
|
||||
{
|
||||
abortfunc = (func != NULL) ? func : &mabort;
|
||||
|
||||
/* These hooks may not be safely inserted if malloc is already in use. */
|
||||
if (!__malloc_initialized && !mcheck_used)
|
||||
{
|
||||
old_free_hook = __free_hook;
|
||||
__free_hook = freehook;
|
||||
old_malloc_hook = __malloc_hook;
|
||||
__malloc_hook = mallochook;
|
||||
old_realloc_hook = __realloc_hook;
|
||||
__realloc_hook = reallochook;
|
||||
mcheck_used = 1;
|
||||
}
|
||||
|
||||
return mcheck_used ? 0 : -1;
|
||||
}
|
||||
|
||||
enum mcheck_status
|
||||
mprobe (__ptr_t ptr)
|
||||
{
|
||||
return mcheck_used ? checkhdr (ptr) : MCHECK_DISABLED;
|
||||
}
|
70
malloc/mcheck.h
Normal file
70
malloc/mcheck.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _MCHECK_H
|
||||
#define _MCHECK_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
#undef __P
|
||||
#define __P(args) args
|
||||
#undef __ptr_t
|
||||
#define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
#undef __P
|
||||
#define __P(args) ()
|
||||
#undef __ptr_t
|
||||
#define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
|
||||
/* Return values for `mprobe': these are the kinds of inconsistencies that
|
||||
`mcheck' enables detection of. */
|
||||
enum mcheck_status
|
||||
{
|
||||
MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
|
||||
MCHECK_OK, /* Block is fine. */
|
||||
MCHECK_FREE, /* Block freed twice. */
|
||||
MCHECK_HEAD, /* Memory before the block was clobbered. */
|
||||
MCHECK_TAIL /* Memory after the block was clobbered. */
|
||||
};
|
||||
|
||||
|
||||
/* Activate a standard collection of debugging hooks. This must be called
|
||||
before `malloc' is ever called. ABORTFUNC is called with an error code
|
||||
(see enum above) when an inconsistency is detected. If ABORTFUNC is
|
||||
null, the standard function prints on stderr and then calls `abort'. */
|
||||
extern int mcheck __P ((void (*__abortfunc) __P ((enum mcheck_status))));
|
||||
|
||||
/* Check for aberrations in a particular malloc'd block. You must have
|
||||
called `mcheck' already. These are the same checks that `mcheck' does
|
||||
when you free or reallocate a block. */
|
||||
extern enum mcheck_status mprobe __P ((__ptr_t __ptr));
|
||||
|
||||
/* Activate a standard collection of tracing hooks. */
|
||||
extern void mtrace __P ((void));
|
||||
extern void muntrace __P ((void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mcheck.h */
|
50
malloc/mtrace.awk
Normal file
50
malloc/mtrace.awk
Normal file
@ -0,0 +1,50 @@
|
||||
#
|
||||
# Awk program to analyze mtrace.c output.
|
||||
#
|
||||
{
|
||||
if ($1 == "@") {
|
||||
where = " (" $2 ")"
|
||||
n = 3
|
||||
} else {
|
||||
where = ""
|
||||
n = 1
|
||||
}
|
||||
if ($n == "+") {
|
||||
if (allocated[$(n+1)] != "")
|
||||
print "+", $(n+1), "Alloc", NR, "duplicate:", allocated[$(n+1)], wherewas[$(n+1)], where;
|
||||
else {
|
||||
wherewas[$(n+1)] = where;
|
||||
allocated[$(n+1)] = $(n+2);
|
||||
}
|
||||
} else if ($n == "-") {
|
||||
if (allocated[$(n+1)] != "") {
|
||||
wherewas[$(n+1)] = "";
|
||||
allocated[$(n+1)] = "";
|
||||
if (allocated[$(n+1)] != "")
|
||||
print "DELETE FAILED", $(n+1), allocated[$(n+1)];
|
||||
} else
|
||||
print "-", $(n+1), "Free", NR, "was never alloc'd", where;
|
||||
} else if ($n == "<") {
|
||||
if (allocated[$(n+1)] != "") {
|
||||
wherewas[$(n+1)] = "";
|
||||
allocated[$(n+1)] = "";
|
||||
} else
|
||||
print "-", $(n+1), "Realloc", NR, "was never alloc'd", where;
|
||||
} else if ($n == ">") {
|
||||
if (allocated[$(n+1)] != "")
|
||||
print "+", $(n+1), "Realloc", NR, "duplicate:", allocated[$(n+1)], where;
|
||||
else {
|
||||
wherewas[$(n+1)] = $(n+2);
|
||||
allocated[$(n+1)] = $(n+2);
|
||||
}
|
||||
} else if ($n == "=") {
|
||||
# Ignore "= Start"
|
||||
} else if ($n == "!") {
|
||||
# Ignore failed realloc attempts for now
|
||||
}
|
||||
}
|
||||
END {
|
||||
for (x in allocated)
|
||||
if (allocated[x] != "")
|
||||
print "+", x, allocated[x], wherewas[x];
|
||||
}
|
211
malloc/mtrace.c
Normal file
211
malloc/mtrace.c
Normal file
@ -0,0 +1,211 @@
|
||||
/* More debugging hooks for `malloc'.
|
||||
Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
Written April 2, 1991 by John Gilmore of Cygnus Support.
|
||||
Based on mcheck.c by Mike Haertel.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
The author may be reached (Email) at the address mike@ai.mit.edu,
|
||||
or (US mail) as Mike Haertel c/o Free Software Foundation. */
|
||||
|
||||
#ifndef _MALLOC_INTERNAL
|
||||
#define _MALLOC_INTERNAL
|
||||
#include <malloc.h>
|
||||
#include <mcheck.h>
|
||||
#include <libc-lock.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __GNU_LIBRARY__
|
||||
extern char *getenv ();
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static FILE *mallstream;
|
||||
static char mallenv[]= "MALLOC_TRACE";
|
||||
static char mallbuf[BUFSIZ]; /* Buffer for the output. */
|
||||
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
/* Address to breakpoint on accesses to... */
|
||||
__ptr_t mallwatch;
|
||||
|
||||
/* File name and line number information, for callers that had
|
||||
the foresight to call through a macro. */
|
||||
char *_mtrace_file;
|
||||
int _mtrace_line;
|
||||
|
||||
/* Old hook values. */
|
||||
static void (*tr_old_free_hook) __P ((__ptr_t ptr));
|
||||
static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size));
|
||||
static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
|
||||
|
||||
/* This function is called when the block being alloc'd, realloc'd, or
|
||||
freed has an address matching the variable "mallwatch". In a debugger,
|
||||
set "mallwatch" to the address of interest, then put a breakpoint on
|
||||
tr_break. */
|
||||
|
||||
void tr_break __P ((void));
|
||||
void
|
||||
tr_break ()
|
||||
{
|
||||
}
|
||||
|
||||
static void tr_where __P ((void));
|
||||
static void
|
||||
tr_where ()
|
||||
{
|
||||
if (_mtrace_file)
|
||||
{
|
||||
fprintf (mallstream, "@ %s:%d ", _mtrace_file, _mtrace_line);
|
||||
_mtrace_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void tr_freehook __P ((__ptr_t));
|
||||
static void
|
||||
tr_freehook (ptr)
|
||||
__ptr_t ptr;
|
||||
{
|
||||
tr_where ();
|
||||
fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */
|
||||
if (ptr == mallwatch)
|
||||
tr_break ();
|
||||
__libc_lock_lock (lock);
|
||||
__free_hook = tr_old_free_hook;
|
||||
free (ptr);
|
||||
__free_hook = tr_freehook;
|
||||
__libc_lock_unlock (lock);
|
||||
}
|
||||
|
||||
static __ptr_t tr_mallochook __P ((__malloc_size_t));
|
||||
static __ptr_t
|
||||
tr_mallochook (size)
|
||||
__malloc_size_t size;
|
||||
{
|
||||
__ptr_t hdr;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
__malloc_hook = tr_old_malloc_hook;
|
||||
hdr = (__ptr_t) malloc (size);
|
||||
__malloc_hook = tr_mallochook;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
tr_where ();
|
||||
/* We could be printing a NULL here; that's OK. */
|
||||
fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
|
||||
|
||||
if (hdr == mallwatch)
|
||||
tr_break ();
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t));
|
||||
static __ptr_t
|
||||
tr_reallochook (ptr, size)
|
||||
__ptr_t ptr;
|
||||
__malloc_size_t size;
|
||||
{
|
||||
__ptr_t hdr;
|
||||
|
||||
if (ptr == mallwatch)
|
||||
tr_break ();
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
__free_hook = tr_old_free_hook;
|
||||
__malloc_hook = tr_old_malloc_hook;
|
||||
__realloc_hook = tr_old_realloc_hook;
|
||||
hdr = (__ptr_t) realloc (ptr, size);
|
||||
__free_hook = tr_freehook;
|
||||
__malloc_hook = tr_mallochook;
|
||||
__realloc_hook = tr_reallochook;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
tr_where ();
|
||||
if (hdr == NULL)
|
||||
/* Failed realloc. */
|
||||
fprintf (mallstream, "! %p %lx\n", ptr, (unsigned long)size);
|
||||
else if (ptr == NULL)
|
||||
fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
|
||||
else
|
||||
fprintf (mallstream, "< %p\n> %p %lx\n", ptr, hdr, (unsigned long)size);
|
||||
|
||||
if (hdr == mallwatch)
|
||||
tr_break ();
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
/* We enable tracing if either the environment variable MALLOC_TRACE
|
||||
is set, or if the variable mallwatch has been patched to an address
|
||||
that the debugging user wants us to stop on. When patching mallwatch,
|
||||
don't forget to set a breakpoint on tr_break! */
|
||||
|
||||
void
|
||||
mtrace ()
|
||||
{
|
||||
char *mallfile;
|
||||
|
||||
/* Don't panic if we're called more than once. */
|
||||
if (mallstream != NULL)
|
||||
return;
|
||||
|
||||
#ifdef _LIBC
|
||||
/* When compiling the GNU libc we use the secure getenv function
|
||||
which prevents the misuse in case of SUID or SGID enabled
|
||||
programs. */
|
||||
mallfile = __secure_getenv (mallenv);
|
||||
#else
|
||||
mallfile = getenv (mallenv);
|
||||
#endif
|
||||
if (mallfile != NULL || mallwatch != NULL)
|
||||
{
|
||||
mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
|
||||
if (mallstream != NULL)
|
||||
{
|
||||
/* Be sure it doesn't malloc its buffer! */
|
||||
setbuf (mallstream, mallbuf);
|
||||
fprintf (mallstream, "= Start\n");
|
||||
tr_old_free_hook = __free_hook;
|
||||
__free_hook = tr_freehook;
|
||||
tr_old_malloc_hook = __malloc_hook;
|
||||
__malloc_hook = tr_mallochook;
|
||||
tr_old_realloc_hook = __realloc_hook;
|
||||
__realloc_hook = tr_reallochook;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
muntrace ()
|
||||
{
|
||||
if (mallstream == NULL)
|
||||
return;
|
||||
|
||||
fprintf (mallstream, "= End\n");
|
||||
fclose (mallstream);
|
||||
mallstream = NULL;
|
||||
__free_hook = tr_old_free_hook;
|
||||
__malloc_hook = tr_old_malloc_hook;
|
||||
__realloc_hook = tr_old_realloc_hook;
|
||||
}
|
Reference in New Issue
Block a user