From 7708a89c60e7b024d31c48c8034932c5e9f0aceb Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Thu, 30 Jun 2011 18:32:03 +0200 Subject: libc: Add logcat error message for memory corruption Our dlmalloc implementation currently calls abort() when it detects that the heap is corrupted, or that an invalid pointer is passed to one of its functions. The only way to detect this is because abort() will force-fully crash the current program with a magic fault address of '0xdeadbaad'. However, this is not really well documented, and a frequent topic on the android-ndk forum (among others). This change makes our dlmalloc code dump a simple message to the log just before the abort() call (and hence before the stack trace) to better help identify the problem. Change-Id: Iebf7eb7fe26463ecadfaca8f247d237edb441e3c --- libc/bionic/dlmalloc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'libc/bionic/dlmalloc.c') diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c index 19fbb7521..035dbac59 100644 --- a/libc/bionic/dlmalloc.c +++ b/libc/bionic/dlmalloc.c @@ -2265,13 +2265,53 @@ static void reset_on_error(mstate m); #else /* PROCEED_ON_ERROR */ -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ +/* The following Android-specific code is used to print an informative + * fatal error message to the log when we detect that a heap corruption + * was detected. We need to be careful about not using a log function + * that may require an allocation here! + */ +#ifdef __ANDROID__ + +# include + +static void __bionic_heap_error(const char* msg, const char* function) +{ + /* We format the buffer explicitely, i.e. without using snprintf() + * which may use malloc() internally. Not something we can trust + * if we just detected a corrupted heap. + */ + char buffer[256]; + strlcpy(buffer, "@@@ ABORTING: ", sizeof(buffer)); + strlcat(buffer, msg, sizeof(buffer)); + if (function != NULL) { + strlcat(buffer, " IN ", sizeof(buffer)); + strlcat(buffer, function, sizeof(buffer)); + } + __libc_android_log_write(ANDROID_LOG_FATAL,"libc","%s", buffer); + abort(); +} + +# ifndef CORRUPTION_ERROR_ACTION +# define CORRUPTION_ERROR_ACTION(m) \ + __bionic_heap_error("HEAP MEMORY CORRUPTION", __FUNCTION__) +# endif +# ifndef USAGE_ERROR_ACTION +# define USAGE_ERROR_ACTION(m,p) \ + __bionic_heap_error("INVALID HEAP ADDRESS", __FUNCTION__) +# endif + +#else /* !__ANDROID__ */ + +# ifndef CORRUPTION_ERROR_ACTION +# define CORRUPTION_ERROR_ACTION(m) ABORT +# endif /* CORRUPTION_ERROR_ACTION */ + +# ifndef USAGE_ERROR_ACTION +# define USAGE_ERROR_ACTION(m,p) ABORT +# endif /* USAGE_ERROR_ACTION */ + +#endif /* !__ANDROID__ */ -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m,p) ABORT -#endif /* USAGE_ERROR_ACTION */ #endif /* PROCEED_ON_ERROR */ -- cgit v1.2.3