Use mmap for allocation of buffers used for __abort_msg

This commit is contained in:
Ulrich Drepper 2011-05-15 00:34:48 -04:00
parent fc317541ab
commit f8a3b5bf8f
9 changed files with 131 additions and 95 deletions

View File

@ -1,5 +1,23 @@
2011-05-15 Ulrich Drepper <drepper@gmail.com>
[BZ #11901]
* include/stdlib.h: Move include protection to the right place.
Define abort_msg_s. Declare __abort_msg with it.
* stdlib/abort.c (__abort_msg): Adjust type.
* assert/assert.c (__assert_fail_base): New function. Majority
of code from __assert_fail. Allocate memory for __abort_msg with
mmap.
(__assert_fail): Now call __assert_fail_base.
* assert/assert-perr.c: Remove bulk of implementation. Use
__assert_fail_base.
* include/assert.hL Declare __assert_fail_base.
* sysdeps/posix/libc_fatal.c: Allocate memory for __abort_msg with
mmap.
* sysdeps/unix/sysv/linux/libc_fatal.c: Likewise.
2011-05-14 Ulrich Drepper <drepper@gmail.com>
[BZ #11952]
[BZ #12453]
* elf/dl-open.c (dl_open_worker): Delay calls to _dl_update_slotinfo
until all modules are registered in the DTV.

12
NEWS
View File

@ -9,12 +9,12 @@ Version 2.14
* The following bugs are resolved with this release:
386, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947,
11952, 12052, 12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432,
12445, 12449, 12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511,
12518, 12527, 12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601,
12611, 12625, 12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685,
12711, 12713, 12714, 12717, 12723, 12724, 12734, 12738
386, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11901, 11945,
11947, 11952, 12052, 12083, 12158, 12178, 12200, 12346, 12393, 12420,
12432, 12445, 12449, 12453, 12454, 12460, 12469, 12489, 12509, 12510,
12511, 12518, 12527, 12541, 12545, 12551, 12582, 12583, 12587, 12597,
12601, 12611, 12625, 12626, 12631, 12650, 12653, 12655, 12660, 12681,
12685, 12711, 12713, 12714, 12717, 12723, 12724, 12734, 12738
* The RPC implementation in libc is obsoleted. Old programs keep working
but new programs cannot be linked with the routines in libc anymore.

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1994-1998,2001,2002,2005,2009 Free Software Foundation, Inc.
/* Copyright (C) 1994-1998,2001,2002,2005,2009,2011
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -17,66 +18,23 @@
02111-1307 USA. */
#include <assert.h>
#include <atomic.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysdep.h>
#include <unistd.h>
extern const char *__progname;
#ifdef USE_IN_LIBIO
# include <wchar.h>
# include <libio/iolibio.h>
# define fflush(s) INTUSE(_IO_fflush) (s)
#endif
/* This function, when passed an error number, a filename, and a line
number, prints a message on the standard error stream of the form:
a.c:10: foobar: Unexpected error: Computer bought the farm
a.c:10: foobar: Unexpected error: Computer bought the farm
It then aborts program execution via a call to `abort'. */
#ifdef FATAL_PREPARE_INCLUDE
# include FATAL_PREPARE_INCLUDE
#endif
void
__assert_perror_fail (int errnum,
const char *file, unsigned int line,
const char *function)
{
char errbuf[1024];
char *buf;
#ifdef FATAL_PREPARE
FATAL_PREPARE;
#endif
if (__asprintf (&buf, _("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
__progname, __progname[0] ? ": " : "",
file, line,
function ? function : "", function ? ": " : "",
__strerror_r (errnum, errbuf, sizeof errbuf)) >= 0)
{
/* Print the message. */
(void) __fxprintf (NULL, "%s", buf);
(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);
}
else
{
/* At least print a minimal message. */
static const char errstr[] = "Unexpected error.\n";
__libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
}
abort ();
char *e = __strerror_r (errnum, errbuf, sizeof errbuf);
__assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
e, file, line, function);
}
libc_hidden_def (__assert_perror_fail)

View File

@ -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)

View File

@ -5,7 +5,7 @@
so it has to be repeated here. */
extern void __assert_fail (__const char *__assertion, __const char *__file,
unsigned int __line, __const char *__function)
__THROW __attribute__ ((__noreturn__));
__THROW __attribute__ ((__noreturn__));
/* Likewise, but prints the error text for ERRNUM. */
extern void __assert_perror_fail (int __errnum, __const char *__file,
@ -13,6 +13,12 @@ extern void __assert_perror_fail (int __errnum, __const char *__file,
__const char *__function)
__THROW __attribute__ ((__noreturn__));
/* The real implementation of the two functions above. */
extern void __assert_fail_base (const char *fmt, const char *assertion,
const char *file, unsigned int line,
const char *function)
__THROW __attribute__ ((__noreturn__));
#if !defined NOT_IN_libc || defined IS_IN_rtld
hidden_proto (__assert_fail)
hidden_proto (__assert_perror_fail)

View File

@ -223,16 +223,21 @@ extern int __qfcvt_r (long double __value, int __ndigit,
# define __cxa_atexit(func, arg, d) INTUSE(__cxa_atexit) (func, arg, d)
# endif
#endif
extern void *__default_morecore (ptrdiff_t) __THROW;
libc_hidden_proto (__default_morecore)
extern char *__abort_msg;
struct abort_msg_s
{
unsigned int size;
char msg[0];
};
extern struct abort_msg_s *__abort_msg;
libc_hidden_proto (__abort_msg)
__END_DECLS
#endif
#undef __Need_M_And_C
#endif /* include/stdlib.h */

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991,93,1995-1998,2001,02,2009 Free Software Foundation, Inc.
/* Copyright (C) 1991,1993,1995-1998,2001,2002,2009,2011
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -37,7 +38,7 @@
#endif
/* Exported variable to locate abort message in core files etc. */
char *__abort_msg __attribute__ ((nocommon));
struct abort_msg_s *__abort_msg __attribute__ ((nocommon));
libc_hidden_def (__abort_msg)
/* We must avoid to run in circles. Therefore we remember how far we

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993-1995,1997,2000,2004,2005,2009
/* Copyright (C) 1993-1995,1997,2000,2004,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>
@ -125,18 +126,28 @@ __libc_message (int do_abort, const char *fmt, ...)
if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == 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';
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 (buf != MAP_FAILED)
{
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. */
char *old = atomic_exchange_acq (&__abort_msg, buf);
free (old);
/* 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);
}
}
}

View File

@ -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';
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. */
char *old = atomic_exchange_acq (&__abort_msg, buf);
free (old);
/* 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);
}
}
}