mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
9ed8fb9bbc
commit
2483ad581a
|
|
@ -1,3 +1,13 @@
|
||||||
|
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
(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)
|
||||||
(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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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);
|
||||||
/* 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__)
|
||||||
__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);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* Generates recursive malloc call on i386-freebsd4.10 with -fmudflap. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
char *p = malloc (1<<24);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue