Commit 2483ad58 by James E Wilson Committed by Jim Wilson

Fix FreeBSD failure with recursive malloc call.

* mf-hooks1.c (malloc, calloc, realloc, free,
__mf_wrap_alloca_indirect): Call BEGIN_MALLOC_PROTECT before calling
the real routines, and END_MALLOC_PROTECT afterwards.
* mf-impl.h (enum __mf_state_enum): Expand comment.  Add in_malloc.
(BEGIN_PROTECT): Handle in_malloc state.
(BEGIN_MALLOC_PROTECT, END_MALLOC_PROTECT): New.
* testsuite/libmudflap.c/hook2-allocstuff.c: New.

From-SVN: r103256
parent 9ed8fb9b
2005-08-17 Jim Wilson <wilson@specifix.com>
* mf-hooks1.c (malloc, calloc, realloc, free,
__mf_wrap_alloca_indirect): Call BEGIN_MALLOC_PROTECT before calling
the real routines, and END_MALLOC_PROTECT afterwards.
* mf-impl.h (enum __mf_state_enum): Expand comment. Add in_malloc.
(BEGIN_PROTECT): Handle in_malloc state.
(BEGIN_MALLOC_PROTECT, END_MALLOC_PROTECT): New.
* testsuite/libmudflap.c/hook2-allocstuff.c: New.
2005-08-17 Kelley Cook <kcook@gcc.gnu.org> 2005-08-17 Kelley Cook <kcook@gcc.gnu.org>
* All files: Update FSF address. * All files: Update FSF address.
......
...@@ -108,7 +108,9 @@ WRAPPER(void *, malloc, size_t c) ...@@ -108,7 +108,9 @@ WRAPPER(void *, malloc, size_t c)
size_with_crumple_zones = size_with_crumple_zones =
CLAMPADD(c,CLAMPADD(__mf_opts.crumple_zone, CLAMPADD(c,CLAMPADD(__mf_opts.crumple_zone,
__mf_opts.crumple_zone)); __mf_opts.crumple_zone));
BEGIN_MALLOC_PROTECT ();
result = (char *) CALL_REAL (malloc, size_with_crumple_zones); result = (char *) CALL_REAL (malloc, size_with_crumple_zones);
END_MALLOC_PROTECT ();
if (LIKELY(result)) if (LIKELY(result))
{ {
...@@ -145,7 +147,9 @@ WRAPPER(void *, calloc, size_t c, size_t n) ...@@ -145,7 +147,9 @@ WRAPPER(void *, calloc, size_t c, size_t n)
CLAMPADD((c * n), /* XXX: CLAMPMUL */ CLAMPADD((c * n), /* XXX: CLAMPMUL */
CLAMPADD(__mf_opts.crumple_zone, CLAMPADD(__mf_opts.crumple_zone,
__mf_opts.crumple_zone)); __mf_opts.crumple_zone));
BEGIN_MALLOC_PROTECT ();
result = (char *) CALL_REAL (malloc, size_with_crumple_zones); result = (char *) CALL_REAL (malloc, size_with_crumple_zones);
END_MALLOC_PROTECT ();
if (LIKELY(result)) if (LIKELY(result))
memset (result, 0, size_with_crumple_zones); memset (result, 0, size_with_crumple_zones);
...@@ -187,7 +191,9 @@ WRAPPER(void *, realloc, void *buf, size_t c) ...@@ -187,7 +191,9 @@ WRAPPER(void *, realloc, void *buf, size_t c)
size_with_crumple_zones = size_with_crumple_zones =
CLAMPADD(c, CLAMPADD(__mf_opts.crumple_zone, CLAMPADD(c, CLAMPADD(__mf_opts.crumple_zone,
__mf_opts.crumple_zone)); __mf_opts.crumple_zone));
BEGIN_MALLOC_PROTECT ();
result = (char *) CALL_REAL (realloc, base, size_with_crumple_zones); result = (char *) CALL_REAL (realloc, base, size_with_crumple_zones);
END_MALLOC_PROTECT ();
/* Ensure heap wiping doesn't occur during this peculiar /* Ensure heap wiping doesn't occur during this peculiar
unregister/reregister pair. */ unregister/reregister pair. */
...@@ -272,7 +278,9 @@ WRAPPER(void, free, void *buf) ...@@ -272,7 +278,9 @@ WRAPPER(void, free, void *buf)
(void *) freeme, (void *) freeme,
__mf_opts.crumple_zone); __mf_opts.crumple_zone);
} }
BEGIN_MALLOC_PROTECT ();
CALL_REAL (free, freeme); CALL_REAL (free, freeme);
END_MALLOC_PROTECT ();
} }
} }
else else
...@@ -287,7 +295,9 @@ WRAPPER(void, free, void *buf) ...@@ -287,7 +295,9 @@ WRAPPER(void, free, void *buf)
(void *) buf, (void *) buf,
__mf_opts.crumple_zone); __mf_opts.crumple_zone);
} }
BEGIN_MALLOC_PROTECT ();
CALL_REAL (free, base); CALL_REAL (free, base);
END_MALLOC_PROTECT ();
} }
} }
...@@ -420,8 +430,10 @@ __mf_wrap_alloca_indirect (size_t c) ...@@ -420,8 +430,10 @@ __mf_wrap_alloca_indirect (size_t c)
{ {
struct alloca_tracking *next = alloca_history->next; struct alloca_tracking *next = alloca_history->next;
__mf_unregister (alloca_history->ptr, 0, __MF_TYPE_HEAP); __mf_unregister (alloca_history->ptr, 0, __MF_TYPE_HEAP);
BEGIN_MALLOC_PROTECT ();
CALL_REAL (free, alloca_history->ptr); CALL_REAL (free, alloca_history->ptr);
CALL_REAL (free, alloca_history); CALL_REAL (free, alloca_history);
END_MALLOC_PROTECT ();
alloca_history = next; alloca_history = next;
} }
...@@ -429,14 +441,20 @@ __mf_wrap_alloca_indirect (size_t c) ...@@ -429,14 +441,20 @@ __mf_wrap_alloca_indirect (size_t c)
result = NULL; result = NULL;
if (LIKELY (c > 0)) /* alloca(0) causes no allocation. */ if (LIKELY (c > 0)) /* alloca(0) causes no allocation. */
{ {
BEGIN_MALLOC_PROTECT ();
track = (struct alloca_tracking *) CALL_REAL (malloc, track = (struct alloca_tracking *) CALL_REAL (malloc,
sizeof (struct alloca_tracking)); sizeof (struct alloca_tracking));
END_MALLOC_PROTECT ();
if (LIKELY (track != NULL)) if (LIKELY (track != NULL))
{ {
BEGIN_MALLOC_PROTECT ();
result = CALL_REAL (malloc, c); result = CALL_REAL (malloc, c);
END_MALLOC_PROTECT ();
if (UNLIKELY (result == NULL)) if (UNLIKELY (result == NULL))
{ {
BEGIN_MALLOC_PROTECT ();
CALL_REAL (free, track); CALL_REAL (free, track);
END_MALLOC_PROTECT ();
/* Too bad. XXX: What about errno? */ /* Too bad. XXX: What about errno? */
} }
else else
......
...@@ -94,9 +94,17 @@ extern int __mf_heuristic_check (uintptr_t, uintptr_t); ...@@ -94,9 +94,17 @@ extern int __mf_heuristic_check (uintptr_t, uintptr_t);
/* Type definitions. */ /* Type definitions. */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
/* The mf_state type codes describe recursion and initialization order. */ /* The mf_state type codes describe recursion and initialization order.
enum __mf_state_enum { active, reentrant }; reentrant means we are inside a mf-runtime support routine, such as
__mf_register, and thus there should be no calls to any wrapped functions,
such as the wrapped malloc. This indicates a bug if it occurs.
in_malloc means we are inside a real malloc call inside a wrapped malloc
call, and thus there should be no calls to any wrapped functions like the
wrapped mmap. This happens on some systems due to how the system libraries
are constructed. */
enum __mf_state_enum { active, reentrant, in_malloc };
/* The __mf_options structure records optional or tunable aspects of the /* The __mf_options structure records optional or tunable aspects of the
mudflap library's behavior. There is a single global instance of this mudflap library's behavior. There is a single global instance of this
...@@ -379,11 +387,23 @@ ret __mfwrap_ ## fname (__VA_ARGS__) ...@@ -379,11 +387,23 @@ ret __mfwrap_ ## fname (__VA_ARGS__)
__mf_reentrancy ++; \ __mf_reentrancy ++; \
return CALL_REAL(fname, __VA_ARGS__); \ return CALL_REAL(fname, __VA_ARGS__); \
} \ } \
else if (UNLIKELY (__mf_get_state () == in_malloc)) \
{ \
return CALL_REAL(fname, __VA_ARGS__); \
} \
else \ else \
{ \ { \
TRACE ("%s\n", __PRETTY_FUNCTION__); \ TRACE ("%s\n", __PRETTY_FUNCTION__); \
} }
/* There is an assumption here that these will only be called in routines
that call BEGIN_PROTECT at the start, and hence the state must always
be active when BEGIN_MALLOC_PROTECT is called. */
#define BEGIN_MALLOC_PROTECT() \
__mf_set_state (in_malloc)
#define END_MALLOC_PROTECT() \
__mf_set_state (active)
/* Unlocked variants of main entry points from mf-runtime.h. */ /* Unlocked variants of main entry points from mf-runtime.h. */
extern void __mfu_check (void *ptr, size_t sz, int type, const char *location); extern void __mfu_check (void *ptr, size_t sz, int type, const char *location);
......
/* Generates recursive malloc call on i386-freebsd4.10 with -fmudflap. */
#include <stdlib.h>
int
main (void)
{
char *p = malloc (1<<24);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment