diff options
Diffstat (limited to 'malloc')
| -rw-r--r-- | malloc/Makefile | 21 | ||||
| -rw-r--r-- | malloc/malloc.c | 117 | ||||
| -rw-r--r-- | malloc/malloc.h | 21 | ||||
| -rw-r--r-- | malloc/mcheck.c | 41 | ||||
| -rw-r--r-- | malloc/mtrace.awk | 50 | ||||
| -rw-r--r-- | malloc/mtrace.c | 83 | ||||
| -rw-r--r-- | malloc/mtrace.pl | 192 |
7 files changed, 434 insertions, 91 deletions
diff --git a/malloc/Makefile b/malloc/Makefile index b43ce136cd..addabf12f8 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -27,7 +27,7 @@ dist-headers := malloc.h headers := $(dist-headers) obstack.h tests := mallocbug -distribute = thread-m.h mtrace.awk mcheck-init.c mcheck.h +distribute = thread-m.h mtrace.pl mcheck-init.c mcheck.h # Things which get pasted together into gmalloc.c. gmalloc-routines := malloc morecore @@ -41,6 +41,19 @@ non-lib.a := libmcheck.a # These should be removed by `make clean'. extra-objs = mcheck-init.o libmcheck.a +# The AWK script to analyze the output of the mtrace functions. +ifneq ($(PERL),no) +install-bin = mtrace + +# The Perl script will print addresses and to do this nicely we must know +# whether we are on a 32 or 64 bit machine. +ifneq ($strip($(findstring wordsize-32,$(config-sysdirs))),) +address-width=10 +else +address-width=18 +endif +endif + include ../Rules $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o @@ -52,3 +65,9 @@ lib: $(objpfx)libmcheck.a # Uncomment this for test releases. For public releases it is too expensive. #CPPFLAGS-malloc.o += -DMALLOC_DEBUG + +$(objpfx)mtrace: mtrace.pl + rm -fr %@.new + sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \ + -e 's|@VERSION@|$(version)|' $^ > $@.new \ + && rm -fr $@ && mv $@.new $@ && chmod +x $@ diff --git a/malloc/malloc.c b/malloc/malloc.c index fb51483279..17350eb426 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1178,7 +1178,19 @@ static int main_trim(size_t pad); #ifndef NO_THREADS static int heap_trim(heap_info *heap, size_t pad); #endif -#if defined(_LIBC) || defined(MALLOC_HOOKS) +#ifdef _LIBC +static Void_t* malloc_check(size_t sz, const Void_t *caller); +static void free_check(Void_t* mem, const Void_t *caller); +static Void_t* realloc_check(Void_t* oldmem, size_t bytes, + const Void_t *caller); +static Void_t* memalign_check(size_t alignment, size_t bytes, + const Void_t *caller); +static Void_t* malloc_starter(size_t sz, const Void_t *caller); +static void free_starter(Void_t* mem, const Void_t *caller); +static Void_t* malloc_atfork(size_t sz, const Void_t *caller); +static void free_atfork(Void_t* mem, const Void_t *caller); +#else +#ifdef MALLOC_HOOKS static Void_t* malloc_check(size_t sz); static void free_check(Void_t* mem); static Void_t* realloc_check(Void_t* oldmem, size_t bytes); @@ -1188,6 +1200,7 @@ static void free_starter(Void_t* mem); static Void_t* malloc_atfork(size_t sz); static void free_atfork(Void_t* mem); #endif +#endif #else @@ -1520,11 +1533,19 @@ int __malloc_initialized = 0; temporarily, because the `atfork' handler mechanism may use malloc/free internally (e.g. in LinuxThreads). */ -#if defined(_LIBC) || defined(MALLOC_HOOKS) +#ifdef _LIBC +static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size, + const __malloc_ptr_t)); +static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr, + const __malloc_ptr_t)); +static Void_t* save_arena; +#else +#ifdef MALLOC_HOOKS static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size)); static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)); static Void_t* save_arena; #endif +#endif static void ptmalloc_lock_all __MALLOC_P((void)) @@ -1639,11 +1660,15 @@ thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \ initialization routine, then do the normal work. */ static Void_t* +#ifdef _LIBC +malloc_hook_ini(size_t sz, const __malloc_ptr_t caller) +#else #if __STD_C malloc_hook_ini(size_t sz) #else malloc_hook_ini(sz) size_t sz; #endif +#endif { __malloc_hook = NULL; __realloc_hook = NULL; @@ -1653,11 +1678,15 @@ malloc_hook_ini(sz) size_t sz; } static Void_t* +#ifdef _LIBC +realloc_hook_ini(Void_t* ptr, size_t sz, const __malloc_ptr_t caller) +#else #if __STD_C realloc_hook_ini(Void_t* ptr, size_t sz) #else realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz; #endif +#endif { __malloc_hook = NULL; __realloc_hook = NULL; @@ -1667,11 +1696,15 @@ realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz; } static Void_t* +#ifdef _LIBC +memalign_hook_ini(size_t sz, size_t alignment, const __malloc_ptr_t caller) +#else #if __STD_C memalign_hook_ini(size_t sz, size_t alignment) #else memalign_hook_ini(sz, alignment) size_t sz; size_t alignment; #endif +#endif { __malloc_hook = NULL; __realloc_hook = NULL; @@ -1681,6 +1714,18 @@ memalign_hook_ini(sz, alignment) size_t sz; size_t alignment; } void weak_variable (*__malloc_initialize_hook) __MALLOC_P ((void)) = NULL; +#ifdef _LIBC +void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr, + const __malloc_ptr_t)) = NULL; +__malloc_ptr_t weak_variable (*__malloc_hook) + __MALLOC_P ((size_t __size, const __malloc_ptr_t)) = malloc_hook_ini; +__malloc_ptr_t weak_variable (*__realloc_hook) + __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size, const __malloc_ptr_t)) + = realloc_hook_ini; +__malloc_ptr_t weak_variable (*__memalign_hook) + __MALLOC_P ((size_t __size, size_t __alignment, const __malloc_ptr_t)) + = memalign_hook_ini; +#else void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)) = NULL; __malloc_ptr_t weak_variable (*__malloc_hook) __MALLOC_P ((size_t __size)) = malloc_hook_ini; @@ -1688,6 +1733,7 @@ __malloc_ptr_t weak_variable (*__realloc_hook) __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size)) = realloc_hook_ini; __malloc_ptr_t weak_variable (*__memalign_hook) __MALLOC_P ((size_t __size, size_t __alignment)) = memalign_hook_ini; +#endif void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL; /* Activate a standard set of debugging hooks. */ @@ -2489,7 +2535,11 @@ Void_t* mALLOc(bytes) size_t bytes; if (__malloc_hook != NULL) { Void_t* result; +#ifdef _LIBC + result = (*__malloc_hook)(bytes, __builtin_return_address (0)); +#else result = (*__malloc_hook)(bytes); +#endif return result; } #endif @@ -2780,7 +2830,11 @@ void fREe(mem) Void_t* mem; #if defined(_LIBC) || defined(MALLOC_HOOKS) if (__free_hook != NULL) { +#ifdef _LIBC + (*__free_hook)(mem, __builtin_return_address (0)); +#else (*__free_hook)(mem); +#endif return; } #endif @@ -2980,7 +3034,11 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; if (__realloc_hook != NULL) { Void_t* result; +#ifdef _LIBC + result = (*__realloc_hook)(oldmem, bytes, __builtin_return_address (0)); +#else result = (*__realloc_hook)(oldmem, bytes); +#endif return result; } #endif @@ -3242,7 +3300,12 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes; if (__memalign_hook != NULL) { Void_t* result; +#ifdef _LIBC + result = (*__memalign_hook)(alignment, bytes, + __builtin_return_address (0)); +#else result = (*__memalign_hook)(alignment, bytes); +#endif return result; } #endif @@ -3413,10 +3476,14 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; #if defined(_LIBC) || defined(MALLOC_HOOKS) if (__malloc_hook != NULL) { sz = n * elem_size; +#ifdef _LIBC + mem = (*__malloc_hook)(sz, __builtin_return_address (0)); +#else mem = (*__malloc_hook)(sz); +#endif if(mem == 0) return 0; -#ifdef HAVE_MEMCPY +#ifdef HAVE_MEMSET return memset(mem, 0, sz); #else while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */ @@ -4106,11 +4173,15 @@ mem2chunk_check(mem) Void_t* mem; } static Void_t* +#ifdef _LIBC +malloc_check(size_t sz, const Void_t *caller) +#else #if __STD_C malloc_check(size_t sz) #else malloc_check(sz) size_t sz; #endif +#endif { mchunkptr victim; INTERNAL_SIZE_T nb = request2size(sz + 1); @@ -4129,11 +4200,15 @@ malloc_check(sz) size_t sz; } static void +#ifdef _LIBC +free_check(Void_t* mem, const Void_t *caller) +#else #if __STD_C free_check(Void_t* mem) #else free_check(mem) Void_t* mem; #endif +#endif { mchunkptr p; @@ -4166,16 +4241,24 @@ free_check(mem) Void_t* mem; } static Void_t* +#ifdef _LIBC +realloc_check(Void_t* oldmem, size_t bytes, const Void_t *caller) +#else #if __STD_C realloc_check(Void_t* oldmem, size_t bytes) #else realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes; #endif +#endif { mchunkptr oldp, newp; INTERNAL_SIZE_T nb, oldsize; +#ifdef _LIBC + if (oldmem == 0) return malloc_check(bytes, NULL); +#else if (oldmem == 0) return malloc_check(bytes); +#endif (void)mutex_lock(&main_arena.mutex); oldp = mem2chunk_check(oldmem); if(!oldp) { @@ -4187,7 +4270,11 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes; case 2: abort(); } +#ifdef _LIBC + return malloc_check(bytes, NULL); +#else return malloc_check(bytes); +#endif } oldsize = chunksize(oldp); @@ -4240,16 +4327,24 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes; } static Void_t* +#ifdef _LIBC +memalign_check(size_t alignment, size_t bytes, const Void_t *caller) +#else #if __STD_C memalign_check(size_t alignment, size_t bytes) #else memalign_check(alignment, bytes) size_t alignment; size_t bytes; #endif +#endif { INTERNAL_SIZE_T nb; mchunkptr p; +#ifdef _LIBC + if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL); +#else if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes); +#endif if (alignment < MINSIZE) alignment = MINSIZE; nb = request2size(bytes+1); @@ -4270,11 +4365,15 @@ memalign_check(alignment, bytes) size_t alignment; size_t bytes; ptmalloc_init() hasn't completed yet. */ static Void_t* +#ifdef _LIBC +malloc_starter(size_t sz, const Void_t *caller) +#else #if __STD_C malloc_starter(size_t sz) #else malloc_starter(sz) size_t sz; #endif +#endif { mchunkptr victim = chunk_alloc(&main_arena, request2size(sz)); @@ -4282,11 +4381,15 @@ malloc_starter(sz) size_t sz; } static void +#ifdef _LIBC +free_starter(Void_t* mem, const Void_t *caller) +#else #if __STD_C free_starter(Void_t* mem) #else free_starter(mem) Void_t* mem; #endif +#endif { mchunkptr p; @@ -4305,11 +4408,15 @@ free_starter(mem) Void_t* mem; is active. */ static Void_t* +#ifdef _LIBC +malloc_atfork (size_t sz, const Void_t *caller) +#else #if __STD_C malloc_atfork(size_t sz) #else malloc_atfork(sz) size_t sz; #endif +#endif { Void_t *vptr = NULL; @@ -4328,11 +4435,15 @@ malloc_atfork(sz) size_t sz; } static void +#ifdef _LIBC +free_atfork(Void_t* mem, const Void_t *caller) +#else #if __STD_C free_atfork(Void_t* mem) #else free_atfork(mem) Void_t* mem; #endif +#endif { Void_t *vptr = NULL; arena *ar_ptr; diff --git a/malloc/malloc.h b/malloc/malloc.h index a72102e607..65381705df 100644 --- a/malloc/malloc.h +++ b/malloc/malloc.h @@ -178,8 +178,25 @@ extern __malloc_ptr_t malloc_get_state __MALLOC_P ((void)); malloc_get_state(). */ extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr)); -#if defined(__GLIBC__) || defined(MALLOC_HOOKS) +#ifdef __GLIBC__ +/* Hooks for debugging versions. */ +extern void (*__malloc_initialize_hook) __MALLOC_P ((void)); +extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr, + __const __malloc_ptr_t)); +extern __malloc_ptr_t (*__malloc_hook) __MALLOC_P ((size_t __size, + __const __malloc_ptr_t)); +extern __malloc_ptr_t (*__realloc_hook) __MALLOC_P ((__malloc_ptr_t __ptr, + size_t __size, + __const __malloc_ptr_t)); +extern __malloc_ptr_t (*__memalign_hook) __MALLOC_P ((size_t __size, + size_t __alignment, + __const __malloc_ptr_t)); +extern void (*__after_morecore_hook) __MALLOC_P ((void)); +/* Activate a standard set of debugging hooks. */ +extern void __malloc_check_init __MALLOC_P ((void)); +#else +#ifdef MALLOC_HOOKS /* Hooks for debugging versions. */ extern void (*__malloc_initialize_hook) __MALLOC_P ((void)); extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)); @@ -192,7 +209,7 @@ extern void (*__after_morecore_hook) __MALLOC_P ((void)); /* Activate a standard set of debugging hooks. */ extern void __malloc_check_init __MALLOC_P ((void)); - +#endif #endif #ifdef __cplusplus diff --git a/malloc/mcheck.c b/malloc/mcheck.c index 1a80a56570..47d35f1f1f 100644 --- a/malloc/mcheck.c +++ b/malloc/mcheck.c @@ -28,9 +28,10 @@ #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)); +static void (*old_free_hook) __P ((__ptr_t ptr, __const __ptr_t)); +static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size, const __ptr_t)); +static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size, + __const __ptr_t)); /* Function to call when something awful happens. */ static void (*abortfunc) __P ((enum mcheck_status)); @@ -91,10 +92,11 @@ checkhdr (hdr) return status; } -static void freehook __P ((__ptr_t)); +static void freehook __P ((__ptr_t, const __ptr_t)); static void -freehook (ptr) +freehook (ptr, caller) __ptr_t ptr; + const __ptr_t caller; { if (ptr) { @@ -105,19 +107,27 @@ freehook (ptr) ptr = (__ptr_t) hdr; } __free_hook = old_free_hook; - free (ptr); + if (old_free_hook != NULL) + (*old_free_hook) (ptr, caller); + else + free (ptr); __free_hook = freehook; } -static __ptr_t mallochook __P ((__malloc_size_t)); +static __ptr_t mallochook __P ((__malloc_size_t, const __ptr_t)); static __ptr_t -mallochook (size) +mallochook (size, caller) __malloc_size_t size; + const __ptr_t caller; { struct hdr *hdr; __malloc_hook = old_malloc_hook; - hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); + if (old_malloc_hook != NULL) + hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1, + caller); + else + hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); __malloc_hook = mallochook; if (hdr == NULL) return NULL; @@ -129,11 +139,12 @@ mallochook (size) return (__ptr_t) (hdr + 1); } -static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t)); +static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t)); static __ptr_t -reallochook (ptr, size) +reallochook (ptr, size, caller) __ptr_t ptr; __malloc_size_t size; + const __ptr_t caller; { struct hdr *hdr; __malloc_size_t osize; @@ -155,7 +166,13 @@ reallochook (ptr, size) __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); + if (old_realloc_hook != NULL) + hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr, + sizeof (struct hdr) + size + 1, + caller); + else + hdr = (struct hdr *) realloc ((__ptr_t) hdr, + sizeof (struct hdr) + size + 1); __free_hook = freehook; __malloc_hook = mallochook; __realloc_hook = reallochook; diff --git a/malloc/mtrace.awk b/malloc/mtrace.awk deleted file mode 100644 index 06844d1a4b..0000000000 --- a/malloc/mtrace.awk +++ /dev/null @@ -1,50 +0,0 @@ -# -# 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]; -} diff --git a/malloc/mtrace.c b/malloc/mtrace.c index 3f0cbb9726..aeefd5600e 100644 --- a/malloc/mtrace.c +++ b/malloc/mtrace.c @@ -1,5 +1,5 @@ /* More debugging hooks for `malloc'. - Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc. Written April 2, 1991 by John Gilmore of Cygnus Support. Based on mcheck.c by Mike Haertel. @@ -28,6 +28,10 @@ #include <bits/libc-lock.h> #endif +#ifdef HAVE_ELF +#include <link.h> +#endif + #include <stdio.h> #ifndef __GNU_LIBRARY__ @@ -51,9 +55,12 @@ 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)); +static void (*tr_old_free_hook) __P ((__ptr_t ptr, const __ptr_t)); +static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size, + const __ptr_t)); +static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, + __malloc_size_t size, + const __ptr_t)); /* This function is called when the block being alloc'd, realloc'd, or freed has an address matching the variable "mallwatch". In a debugger, @@ -66,51 +73,77 @@ tr_break () { } -static void tr_where __P ((void)); +static void tr_where __P ((const __ptr_t)); static void -tr_where () +tr_where (caller) + const __ptr_t caller; { if (_mtrace_file) { fprintf (mallstream, "@ %s:%d ", _mtrace_file, _mtrace_line); _mtrace_file = NULL; } + else if (caller != NULL) + { +#ifdef HAVE_ELF + Dl_info info; + if (_dl_addr (caller, &info)) + { + fprintf (mallstream, "@ %s%s%s%s%s[%p]", + info.dli_fname ?: "", info.dli_fname ? ":" : "", + info.dli_sname ? "(" : "", + info.dli_sname ?: "", info.dli_sname ? ") " : " ", + caller); + } + else +#endif + fprintf (mallstream, "@ [%p] ", caller); + } } -static void tr_freehook __P ((__ptr_t)); +static void tr_freehook __P ((__ptr_t, const __ptr_t)); static void -tr_freehook (ptr) +tr_freehook (ptr, caller) __ptr_t ptr; + const __ptr_t caller; { - tr_where (); - fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */ + tr_where (caller); + /* Be sure to print it first. */ + fprintf (mallstream, "- %p\n", ptr); if (ptr == mallwatch) tr_break (); __libc_lock_lock (lock); __free_hook = tr_old_free_hook; - free (ptr); + if (tr_old_free_hook != NULL) + (*tr_old_free_hook) (ptr, caller); + else + free (ptr); __free_hook = tr_freehook; __libc_lock_unlock (lock); } -static __ptr_t tr_mallochook __P ((__malloc_size_t)); +static __ptr_t tr_mallochook __P ((__malloc_size_t, const __ptr_t)); static __ptr_t -tr_mallochook (size) +tr_mallochook (size, caller) __malloc_size_t size; + const __ptr_t caller; { __ptr_t hdr; __libc_lock_lock (lock); __malloc_hook = tr_old_malloc_hook; - hdr = (__ptr_t) malloc (size); + if (tr_old_malloc_hook != NULL) + hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller); + else + hdr = (__ptr_t) malloc (size); __malloc_hook = tr_mallochook; __libc_lock_unlock (lock); - tr_where (); + tr_where (caller); /* We could be printing a NULL here; that's OK. */ - fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size); + fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size); if (hdr == mallwatch) tr_break (); @@ -118,11 +151,12 @@ tr_mallochook (size) return hdr; } -static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t)); +static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t)); static __ptr_t -tr_reallochook (ptr, size) +tr_reallochook (ptr, size, caller) __ptr_t ptr; __malloc_size_t size; + const __ptr_t caller; { __ptr_t hdr; @@ -134,21 +168,24 @@ tr_reallochook (ptr, size) __free_hook = tr_old_free_hook; __malloc_hook = tr_old_malloc_hook; __realloc_hook = tr_old_realloc_hook; - hdr = (__ptr_t) realloc (ptr, size); + if (tr_old_realloc_hook != NULL) + hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller); + else + hdr = (__ptr_t) realloc (ptr, size); __free_hook = tr_freehook; __malloc_hook = tr_mallochook; __realloc_hook = tr_reallochook; __libc_lock_unlock (lock); - tr_where (); + tr_where (caller); if (hdr == NULL) /* Failed realloc. */ - fprintf (m |
