2004-08-21 Ulrich Drepper <drepper@redhat.com>
+ * malloc/hooks.c (DEFAULT_CHECK_ACTION): Moved to malloc.c.
+ (check_action): Likewise.
+ When printing error messages, use malloc_printf_nc now instead of
+ fiddling with the streams cancellation flag in every place.
+ * malloc/malloc.c (DEFAULT_CHECK_ACTION): New definition. Change
+ default to 3.
+ (check_action): New variable.
+ (unlink): Print error message and eventually terminate in case list
+ is corrupted.
+ (malloc_printf_nc): New function. Use it in _int_free.
+ Change proposed by Arjan van de Ven.
+
* dlfcn/Makefile: Don't build eval.c anymore.
2004-08-20 Roland McGrath <roland@frob.com>
/* Malloc implementation for multiple threads without lock contention.
- Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
/* $Id$ */
-#ifndef DEFAULT_CHECK_ACTION
-#define DEFAULT_CHECK_ACTION 1
-#endif
-
/* What to do if the standard debugging hooks are in place and a
corrupt pointer is detected: do nothing (0), print an error message
(1), or call abort() (2). */
return public_mEMALIGn(alignment, sz);
}
-
-static int check_action = DEFAULT_CHECK_ACTION;
-
/* Whether we are using malloc checking. */
static int using_malloc_checking;
__realloc_hook = realloc_check;
__memalign_hook = memalign_check;
if(check_action & 1)
- {
-#ifdef _LIBC
- _IO_flockfile (stderr);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-#endif
- fprintf(stderr, "malloc: using debugging hooks\n");
-#ifdef _LIBC
- ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
- _IO_funlockfile (stderr);
-#endif
- }
+ malloc_printf_nc (1, "malloc: using debugging hooks\n");
}
/* A simple, standard set of debugging hooks. Overhead is `only' one
if((char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem ||
t == initial_top(&main_arena)) return 0;
- if(check_action & 1)
- {
-#ifdef _LIBC
- _IO_flockfile (stderr);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-#endif
- fprintf(stderr, "malloc: top chunk is corrupt\n");
-#ifdef _LIBC
- ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
- _IO_funlockfile (stderr);
-#endif
- }
- if(check_action & 2)
- abort();
+ malloc_printf_nc (check_action, "malloc: top chunk is corrupt\n");
/* Try to set up a new top chunk. */
brk = MORECORE(0);
p = mem2chunk_check(mem);
if(!p) {
(void)mutex_unlock(&main_arena.mutex);
- if(check_action & 1)
- {
-#ifdef _LIBC
- _IO_flockfile (stderr);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-#endif
- fprintf(stderr, "free(): invalid pointer %p!\n", mem);
-#ifdef _LIBC
- ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
- _IO_funlockfile (stderr);
-#endif
- }
- if(check_action & 2)
- abort();
+
+ malloc_printf_nc(check_action, "free(): invalid pointer %p!\n", mem);
return;
}
#if HAVE_MMAP
oldp = mem2chunk_check(oldmem);
(void)mutex_unlock(&main_arena.mutex);
if(!oldp) {
- if(check_action & 1)
- {
-#ifdef _LIBC
- _IO_flockfile (stderr);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-#endif
- fprintf(stderr, "realloc(): invalid pointer %p!\n", oldmem);
-#ifdef _LIBC
- ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
- _IO_funlockfile (stderr);
-#endif
- }
- if(check_action & 2)
- abort();
+ malloc_printf_nc(check_action, "realloc(): invalid pointer %p!\n", oldmem);
return malloc_check(bytes, NULL);
}
oldsize = chunksize(oldp);
/* For uintptr_t. */
#include <stdint.h>
+/* For va_arg, va_start, va_end. */
+#include <stdarg.h>
+
/*
Debugging:
static void mSTATs(void);
static int mALLOPt(int, int);
static struct mallinfo mALLINFo(mstate);
+static void malloc_printf_nc(int action, const char *template, ...);
static Void_t* internal_function mem2mem_check(Void_t *p, size_t sz);
static int internal_function top_check(void);
#define unlink(P, BK, FD) { \
FD = P->fd; \
BK = P->bk; \
+ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
+ malloc_printf_nc (check_action, \
+ "corrupted double-linked list at %p!\n", P); \
FD->bk = BK; \
BK->fd = FD; \
}
void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL;
+/* ---------------- Error behavior ------------------------------------ */
+
+#ifndef DEFAULT_CHECK_ACTION
+#define DEFAULT_CHECK_ACTION 3
+#endif
+
+static int check_action = DEFAULT_CHECK_ACTION;
+
+
/* ------------------- Support for multiple arenas -------------------- */
#include "arena.c"
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
{
- if (check_action & 1)
- {
-#ifdef _LIBC
- _IO_flockfile (stderr);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-#endif
- fprintf (stderr, "free(): invalid pointer %p!\n", mem);
-#ifdef _LIBC
- ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
- _IO_funlockfile (stderr);
-#endif
- }
- if (check_action & 2)
- abort ();
+ malloc_printf_nc (check_action, "free(): invalid pointer %p!\n", mem);
return;
}
*/
+/* Helper code. */
+
+static void
+malloc_printf_nc(int action, const char *template, ...)
+{
+ if (action & 1)
+ {
+#ifdef _LIBC
+ _IO_flockfile (stderr);
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+#endif
+
+ va_list ap;
+ va_start (ap, template);
+
+ vfprintf (stderr, template, ap);
+
+ va_end (ap);
+
+#ifdef _LIBC
+ ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
+ _IO_funlockfile (stderr);
+#endif
+ }
+ if (action & 2)
+ abort ();
+}
+
#ifdef _LIBC
# include <sys/param.h>