diff options
| author | Elliott Hughes <enh@google.com> | 2013-06-12 14:05:46 -0700 |
|---|---|---|
| committer | Elliott Hughes <enh@google.com> | 2013-06-12 14:14:53 -0700 |
| commit | 61e699a133a4807fe878a6cb0d7190d7c96e21f8 (patch) | |
| tree | 12dd46e7f8e5f7172a3fe0fd9075fa929cbb1001 /libc/stdlib | |
| parent | 5cde15eb17f4ddc0949c0cbd38a46e6c0bad7019 (diff) | |
| download | bionic-61e699a133a4807fe878a6cb0d7190d7c96e21f8.zip bionic-61e699a133a4807fe878a6cb0d7190d7c96e21f8.tar.gz bionic-61e699a133a4807fe878a6cb0d7190d7c96e21f8.tar.bz2 | |
Clean up abort.
* A dlmalloc usage error shouldn't call abort(3) because we want to
cause a SIGSEGV by writing the address dlmalloc didn't like to an
address the kernel won't like, so that debuggerd will dump the
memory around the address that upset dlmalloc.
* Switch to the simpler FreeBSD/NetBSD style of registering stdio
cleanup. Hopefully this will let us simplify more of the stdio
implementation.
* Clear the stdio cleanup handler before we abort because of a dlmalloc
corruption error. This fixes the reported bug, where we'd hang inside
dlmalloc because the stdio cleanup reentered dlmalloc.
Bug: 9301265
Change-Id: Ief31b389455d6876e5a68f0f5429567d37277dbc
Diffstat (limited to 'libc/stdlib')
| -rw-r--r-- | libc/stdlib/atexit.c | 42 |
1 files changed, 2 insertions, 40 deletions
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index 23a2636..8f5bd2d 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -44,7 +44,8 @@ struct atexit *__atexit; * Function pointers are stored in a linked list of pages. The list * is initially empty, and pages are allocated on demand. The first * function pointer in the first allocated page (the last one in - * the linked list) is reserved for the cleanup function. + * the linked list) was reserved for the cleanup function. + * TODO: switch to the regular FreeBSD/NetBSD atexit implementation. * * Outside the following functions, all pages are mprotect()'ed * to prevent unintentional/malicious corruption. @@ -172,42 +173,3 @@ __cxa_finalize(void *dso) } _ATEXIT_UNLOCK(); } - -/* - * Register the cleanup function - */ -void -__atexit_register_cleanup(void (*func)(void)) -{ - struct atexit *p; - int pgsize = getpagesize(); - - if (pgsize < (int)sizeof(*p)) - return; - _ATEXIT_LOCK(); - p = __atexit; - while (p != NULL && p->next != NULL) - p = p->next; - if (p == NULL) { - p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - if (p == MAP_FAILED) - goto unlock; - p->ind = 1; - p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) / - sizeof(p->fns[0]); - p->next = NULL; - __atexit = p; - if (__atexit_invalid) - __atexit_invalid = 0; - } else { - if (mprotect(p, pgsize, PROT_READ | PROT_WRITE)) - goto unlock; - } - p->fns[0].fn_ptr.std_func = func; - p->fns[0].fn_arg = NULL; - p->fns[0].fn_dso = NULL; - mprotect(p, pgsize, PROT_READ); -unlock: - _ATEXIT_UNLOCK(); -} |
