summaryrefslogtreecommitdiff
path: root/malloc/mcheck.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1996-12-20 01:39:50 +0000
committerUlrich Drepper <drepper@redhat.com>1996-12-20 01:39:50 +0000
commit6d52618b15cbe25ed4822ac51321db292f28ccda (patch)
treebafef072c0f5cb67c09d7c1789888d4310ac568f /malloc/mcheck.c
parent10dc2a90b7f86d9bc1be9d1b9305a781882f7ac5 (diff)
Update from main archive 961219cvs/libc-961220
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 Rüdiger 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.
Diffstat (limited to 'malloc/mcheck.c')
-rw-r--r--malloc/mcheck.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
new file mode 100644
index 0000000000..7f1112ea8b
--- /dev/null
+++ b/malloc/mcheck.c
@@ -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;
+}