summaryrefslogtreecommitdiff
path: root/malloc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-03-27 05:36:34 +0000
committerUlrich Drepper <drepper@redhat.com>2000-03-27 05:36:34 +0000
commit8e605e789df868763e388dca7040538c1de41b85 (patch)
tree5c243130cd406eda3e1e2d582535e38d614d36f0 /malloc
parent1edf26ffc696dc0520def24e6a852add3566860e (diff)
downloadglibc-8e605e789df868763e388dca7040538c1de41b85.tar.gz
Update.
2000-03-26 Ulrich Drepper <drepper@redhat.com> * include/features.h: Undef and document __USE_XOPEN2K. * malloc/mcheck.c: Implement pedantic checking of all allocated blocks whenever a function is called. Initiated by calling mcheck_pedantic instead of mcheck. * malloc/mcheck.h: Declare mcheck_pedantic. * malloc/Versions [libc] (GLIBC_2.2): Add mcheck_pedantic. * locale/programs/localdef.c: Use mcheck_pedantic instead of mcheck for now.
Diffstat (limited to 'malloc')
-rw-r--r--malloc/Versions4
-rw-r--r--malloc/mcheck.c95
-rw-r--r--malloc/mcheck.h9
3 files changed, 102 insertions, 6 deletions
diff --git a/malloc/Versions b/malloc/Versions
index 1a4454f22e..43207549a6 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -48,4 +48,8 @@ libc {
# Special functions.
__libc_freeres;
}
+ GLIBC_2.2 {
+ # m*
+ mcheck_pedantic;
+ }
}
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 85258e9dd0..42e8e71174 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -1,5 +1,5 @@
/* Standard debugging hooks for `malloc'.
- Copyright (C) 1990,91,92,93,94,95,96,97,99 Free Software Foundation, Inc.
+ Copyright (C) 1990-1997, 1999, 2000 Free Software Foundation, Inc.
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
@@ -24,6 +24,7 @@
# define _MALLOC_INTERNAL
# include <malloc.h>
# include <mcheck.h>
+# include <stdint.h>
# include <stdio.h>
# include <libintl.h>
#endif
@@ -46,10 +47,19 @@ static void (*abortfunc) __P ((enum mcheck_status));
struct hdr
{
- __malloc_size_t size; /* Exact size requested by user. */
+ __malloc_size_t size; /* Exact size requested by user. */
unsigned long int magic; /* Magic number to check header integrity. */
+ struct hdr *prev;
+ struct hdr *next;
};
+/* This is the beginning of the list of all memory blocks allocated.
+ It is only constructed if the pedantic testing is requested. */
+static struct hdr *root;
+
+/* Nonzero if pedentic checking of all blocks is requested. */
+static int pedantic;
+
#if defined _LIBC || defined STDC_HEADERS || defined USG
# include <string.h>
# define flood memset
@@ -73,7 +83,7 @@ checkhdr (hdr)
const struct hdr *hdr;
{
enum mcheck_status status;
- switch (hdr->magic)
+ switch (hdr->magic ^ ((uintptr_t) hdr->prev + (uintptr_t) hdr->next))
{
default:
status = MCHECK_HEAD;
@@ -93,17 +103,77 @@ checkhdr (hdr)
return status;
}
+static void check_all __P ((void));
+static void
+check_all ()
+{
+ /* Walk through all the active blocks and test whether they were tempered
+ with. */
+ struct hdr *runp = root;
+
+ while (runp != NULL)
+ {
+ (void) checkhdr (runp);
+
+ runp = runp->next;
+ }
+}
+
+static void unlink_blk __P ((struct hdr *ptr));
+static void
+unlink_blk (ptr)
+ struct hdr *ptr;
+{
+ if (ptr->next != NULL)
+ {
+ ptr->next->prev = ptr->prev;
+ ptr->next->magic = MAGICWORD ^ ((uintptr_t) ptr->next->prev
+ + (uintptr_t) ptr->next->next);
+ }
+ if (ptr->prev != NULL)
+ {
+ ptr->prev->next = ptr->next;
+ ptr->prev->magic = MAGICWORD ^ ((uintptr_t) ptr->prev->prev
+ + (uintptr_t) ptr->prev->next);
+ }
+ else
+ root = ptr->next;
+}
+
+static void link_blk __P ((struct hdr *ptr));
+static void
+link_blk (hdr)
+ struct hdr *hdr;
+{
+ hdr->prev = NULL;
+ hdr->next = root;
+ root = hdr;
+ hdr->magic = MAGICWORD ^ (uintptr_t) hdr->next;
+
+ /* And the next block. */
+ if (hdr->next != NULL)
+ {
+ hdr->next->prev = hdr;
+ hdr->next->magic = MAGICWORD ^ ((uintptr_t) hdr
+ + (uintptr_t) hdr->next->next);
+ }
+}
+
static void freehook __P ((__ptr_t, const __ptr_t));
static void
freehook (ptr, caller)
__ptr_t ptr;
const __ptr_t caller;
{
+ if (pedantic)
+ check_all ();
if (ptr)
{
struct hdr *hdr = ((struct hdr *) ptr) - 1;
checkhdr (hdr);
hdr->magic = MAGICFREE;
+ unlink_blk (hdr);
+ hdr->prev = hdr->next = NULL;
flood (ptr, FREEFLOOD, hdr->size);
ptr = (__ptr_t) hdr;
}
@@ -123,6 +193,9 @@ mallochook (size, caller)
{
struct hdr *hdr;
+ if (pedantic)
+ check_all ();
+
__malloc_hook = old_malloc_hook;
if (old_malloc_hook != NULL)
hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
@@ -134,7 +207,7 @@ mallochook (size, caller)
return NULL;
hdr->size = size;
- hdr->magic = MAGICWORD;
+ link_blk (hdr);
((char *) &hdr[1])[size] = MAGICBYTE;
flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
return (__ptr_t) (hdr + 1);
@@ -150,12 +223,16 @@ reallochook (ptr, size, caller)
struct hdr *hdr;
__malloc_size_t osize;
+ if (pedantic)
+ check_all ();
+
if (ptr)
{
hdr = ((struct hdr *) ptr) - 1;
osize = hdr->size;
checkhdr (hdr);
+ unlink_blk (hdr);
if (size < osize)
flood ((char *) ptr + size, FREEFLOOD, osize - size);
}
@@ -181,7 +258,7 @@ reallochook (ptr, size, caller)
return NULL;
hdr->size = size;
- hdr->magic = MAGICWORD;
+ link_blk (hdr);
((char *) &hdr[1])[size] = MAGICBYTE;
if (size > osize)
flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
@@ -244,6 +321,14 @@ mcheck (func)
return mcheck_used ? 0 : -1;
}
+int
+mcheck_pedantic (func)
+ void (*func) __P ((enum mcheck_status));
+{
+ pedantic = 1;
+ return mcheck (func);
+}
+
enum mcheck_status
mprobe (__ptr_t ptr)
{
diff --git a/malloc/mcheck.h b/malloc/mcheck.h
index 5cf2bcd598..9460547d08 100644
--- a/malloc/mcheck.h
+++ b/malloc/mcheck.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999, 2000 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
@@ -41,6 +41,13 @@ enum mcheck_status
null, the standard function prints on stderr and then calls `abort'. */
extern int mcheck (void (*__abortfunc) (enum mcheck_status)) __THROW;
+/* Similar to `mcheck´ but performs checks for all block whenever one of
+ the memory handling functions is called. This can be very slow. */
+extern int mcheck_pedantic (void (*__abortfunc) (enum mcheck_status)) __THROW;
+
+/* Similar to `mcheck', but perform tests on all blocks every time. */
+extern int mcheck_verbose (void (*func) __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. */