about summary refs log tree commit diff
path: root/assert/assert.c
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 /assert/assert.c
parentfc317541ab359b33ed7bf402ead84ba6f112604c (diff)
downloadglibc-f8a3b5bf8fa1d0c43d2458e03cc109a04fdef194.tar.gz
glibc-f8a3b5bf8fa1d0c43d2458e03cc109a04fdef194.tar.xz
glibc-f8a3b5bf8fa1d0c43d2458e03cc109a04fdef194.zip
Use mmap for allocation of buffers used for __abort_msg
Diffstat (limited to 'assert/assert.c')
-rw-r--r--assert/assert.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/assert/assert.c b/assert/assert.c
index 727fb1446c..803015f0f4 100644
--- a/assert/assert.c
+++ b/assert/assert.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1994-1996,1998,2001,2002,2005,2009
+/* Copyright (C) 1991,1994-1996,1998,2001,2002,2005,2009,2011
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -19,11 +19,13 @@
 
 #include <assert.h>
 #include <atomic.h>
+#include <ldsodefs.h>
 #include <libintl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sysdep.h>
 #include <unistd.h>
+#include <sys/mman.h>
 
 
 extern const char *__progname;
@@ -37,7 +39,7 @@ extern const char *__progname;
 /* This function, when passed a string containing an asserted
    expression, a filename, and a line number, prints a message
    on the standard error stream of the form:
-   	a.c:10: foobar: Assertion `a == b' failed.
+	a.c:10: foobar: Assertion `a == b' failed.
    It then aborts program execution via a call to `abort'.  */
 
 #ifdef FATAL_PREPARE_INCLUDE
@@ -45,31 +47,44 @@ extern const char *__progname;
 #endif
 
 
-#undef __assert_fail
 void
-__assert_fail (const char *assertion, const char *file, unsigned int line,
-	       const char *function)
+__assert_fail_base (const char *fmt, const char *assertion, const char *file,
+		    unsigned int line, const char *function)
 {
-  char *buf;
+  char *str;
 
 #ifdef FATAL_PREPARE
   FATAL_PREPARE;
 #endif
 
-  if (__asprintf (&buf, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
+  int total;
+  if (__asprintf (&str, fmt,
 		  __progname, __progname[0] ? ": " : "",
 		  file, line,
 		  function ? function : "", function ? ": " : "",
-		  assertion) >= 0)
+		  assertion, &total) >= 0)
     {
       /* Print the message.  */
-      (void) __fxprintf (NULL, "%s", buf);
+      (void) __fxprintf (NULL, "%s", str);
       (void) fflush (stderr);
 
-      /* 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;
+	  strcpy (buf->msg, str);
+
+	  /* 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);
+	}
+
+      free (str);
     }
   else
     {
@@ -80,4 +95,14 @@ __assert_fail (const char *assertion, const char *file, unsigned int line,
 
   abort ();
 }
+
+
+#undef __assert_fail
+void
+__assert_fail (const char *assertion, const char *file, unsigned int line,
+	       const char *function)
+{
+  __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
+		      assertion, file, line, function);
+}
 hidden_def(__assert_fail)