aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-15 00:34:48 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-15 00:34:48 -0400
commitf8a3b5bf8fa1d0c43d2458e03cc109a04fdef194 (patch)
treec92e262e52b730a8bd4bc3505f46ded142b7cebd /sysdeps/unix
parentfc317541ab359b33ed7bf402ead84ba6f112604c (diff)
downloadglibc-f8a3b5bf8fa1d0c43d2458e03cc109a04fdef194.zip
glibc-f8a3b5bf8fa1d0c43d2458e03cc109a04fdef194.tar.gz
glibc-f8a3b5bf8fa1d0c43d2458e03cc109a04fdef194.tar.bz2
Use mmap for allocation of buffers used for __abort_msg
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/sysv/linux/libc_fatal.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
index 7287f4e..e1b4c8d 100644
--- a/sysdeps/unix/sysv/linux/libc_fatal.c
+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-1995,1997,2000,2002-2005,2009
+/* Copyright (C) 1993-1995,1997,2000,2002-2005,2009,2011
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -20,6 +20,7 @@
#include <atomic.h>
#include <errno.h>
#include <fcntl.h>
+#include <ldsodefs.h>
#include <paths.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -28,6 +29,7 @@
#include <string.h>
#include <sysdep.h>
#include <unistd.h>
+#include <sys/mman.h>
#include <sys/syslog.h>
#include <execinfo.h>
@@ -134,18 +136,28 @@ __libc_message (int do_abort, const char *fmt, ...)
if (cnt == total)
written = true;
- char *buf = do_abort ? malloc (total + 1) : NULL;
- if (buf != NULL)
+ if (do_abort)
{
- char *wp = buf;
- for (int cnt = 0; cnt < nlist; ++cnt)
- wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
- *wp = '\0';
-
- /* We have to free the old buffer since the application might
- catch the SIGABRT signal. */
- char *old = atomic_exchange_acq (&__abort_msg, buf);
- free (old);
+ total = ((total + 1 + GLRO(dl_pagesize) - 1)
+ & ~(GLRO(dl_pagesize) - 1));
+ struct abort_msg_s *buf = __mmap (NULL, total,
+ PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (__builtin_expect (buf != MAP_FAILED, 1))
+ {
+ buf->size = total;
+ char *wp = buf->msg;
+ for (int cnt = 0; cnt < nlist; ++cnt)
+ wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
+ *wp = '\0';
+
+ /* We have to free the old buffer since the application might
+ catch the SIGABRT signal. */
+ struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
+ buf);
+ if (old != NULL)
+ __munmap (old, old->size);
+ }
}
}