Use mmap for allocation of buffers used for __abort_msg
This commit is contained in:
parent
fc317541ab
commit
f8a3b5bf8f
18
ChangeLog
18
ChangeLog
|
@ -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>
|
2011-05-14 Ulrich Drepper <drepper@gmail.com>
|
||||||
|
|
||||||
|
[BZ #11952]
|
||||||
[BZ #12453]
|
[BZ #12453]
|
||||||
* elf/dl-open.c (dl_open_worker): Delay calls to _dl_update_slotinfo
|
* elf/dl-open.c (dl_open_worker): Delay calls to _dl_update_slotinfo
|
||||||
until all modules are registered in the DTV.
|
until all modules are registered in the DTV.
|
||||||
|
|
12
NEWS
12
NEWS
|
@ -9,12 +9,12 @@ Version 2.14
|
||||||
|
|
||||||
* The following bugs are resolved with this release:
|
* The following bugs are resolved with this release:
|
||||||
|
|
||||||
386, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947,
|
386, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11901, 11945,
|
||||||
11952, 12052, 12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432,
|
11947, 11952, 12052, 12083, 12158, 12178, 12200, 12346, 12393, 12420,
|
||||||
12445, 12449, 12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511,
|
12432, 12445, 12449, 12453, 12454, 12460, 12469, 12489, 12509, 12510,
|
||||||
12518, 12527, 12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601,
|
12511, 12518, 12527, 12541, 12545, 12551, 12582, 12583, 12587, 12597,
|
||||||
12611, 12625, 12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685,
|
12601, 12611, 12625, 12626, 12631, 12650, 12653, 12655, 12660, 12681,
|
||||||
12711, 12713, 12714, 12717, 12723, 12724, 12734, 12738
|
12685, 12711, 12713, 12714, 12717, 12723, 12724, 12734, 12738
|
||||||
|
|
||||||
* The RPC implementation in libc is obsoleted. Old programs keep working
|
* The RPC implementation in libc is obsoleted. Old programs keep working
|
||||||
but new programs cannot be linked with the routines in libc anymore.
|
but new programs cannot be linked with the routines in libc anymore.
|
||||||
|
|
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -17,66 +18,23 @@
|
||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <atomic.h>
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.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
|
/* This function, when passed an error number, a filename, and a line
|
||||||
number, prints a message on the standard error stream of the form:
|
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'. */
|
It then aborts program execution via a call to `abort'. */
|
||||||
|
|
||||||
#ifdef FATAL_PREPARE_INCLUDE
|
|
||||||
# include FATAL_PREPARE_INCLUDE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
__assert_perror_fail (int errnum,
|
__assert_perror_fail (int errnum,
|
||||||
const char *file, unsigned int line,
|
const char *file, unsigned int line,
|
||||||
const char *function)
|
const char *function)
|
||||||
{
|
{
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
char *buf;
|
|
||||||
|
|
||||||
#ifdef FATAL_PREPARE
|
char *e = __strerror_r (errnum, errbuf, sizeof errbuf);
|
||||||
FATAL_PREPARE;
|
__assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
|
||||||
#endif
|
e, file, line, function);
|
||||||
|
|
||||||
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 ();
|
|
||||||
}
|
}
|
||||||
libc_hidden_def (__assert_perror_fail)
|
libc_hidden_def (__assert_perror_fail)
|
||||||
|
|
|
@ -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.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
@ -19,11 +19,13 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|
||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
|
@ -37,7 +39,7 @@ extern const char *__progname;
|
||||||
/* This function, when passed a string containing an asserted
|
/* This function, when passed a string containing an asserted
|
||||||
expression, a filename, and a line number, prints a message
|
expression, a filename, and a line number, prints a message
|
||||||
on the standard error stream of the form:
|
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'. */
|
It then aborts program execution via a call to `abort'. */
|
||||||
|
|
||||||
#ifdef FATAL_PREPARE_INCLUDE
|
#ifdef FATAL_PREPARE_INCLUDE
|
||||||
|
@ -45,31 +47,44 @@ extern const char *__progname;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef __assert_fail
|
|
||||||
void
|
void
|
||||||
__assert_fail (const char *assertion, const char *file, unsigned int line,
|
__assert_fail_base (const char *fmt, const char *assertion, const char *file,
|
||||||
const char *function)
|
unsigned int line, const char *function)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *str;
|
||||||
|
|
||||||
#ifdef FATAL_PREPARE
|
#ifdef FATAL_PREPARE
|
||||||
FATAL_PREPARE;
|
FATAL_PREPARE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (__asprintf (&buf, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
|
int total;
|
||||||
|
if (__asprintf (&str, fmt,
|
||||||
__progname, __progname[0] ? ": " : "",
|
__progname, __progname[0] ? ": " : "",
|
||||||
file, line,
|
file, line,
|
||||||
function ? function : "", function ? ": " : "",
|
function ? function : "", function ? ": " : "",
|
||||||
assertion) >= 0)
|
assertion, &total) >= 0)
|
||||||
{
|
{
|
||||||
/* Print the message. */
|
/* Print the message. */
|
||||||
(void) __fxprintf (NULL, "%s", buf);
|
(void) __fxprintf (NULL, "%s", str);
|
||||||
(void) fflush (stderr);
|
(void) fflush (stderr);
|
||||||
|
|
||||||
/* We have to free the old buffer since the application might
|
total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
|
||||||
catch the SIGABRT signal. */
|
struct abort_msg_s *buf = __mmap (NULL, total, PROT_READ | PROT_WRITE,
|
||||||
char *old = atomic_exchange_acq (&__abort_msg, buf);
|
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||||
free (old);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -80,4 +95,14 @@ __assert_fail (const char *assertion, const char *file, unsigned int line,
|
||||||
|
|
||||||
abort ();
|
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)
|
hidden_def(__assert_fail)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
so it has to be repeated here. */
|
so it has to be repeated here. */
|
||||||
extern void __assert_fail (__const char *__assertion, __const char *__file,
|
extern void __assert_fail (__const char *__assertion, __const char *__file,
|
||||||
unsigned int __line, __const char *__function)
|
unsigned int __line, __const char *__function)
|
||||||
__THROW __attribute__ ((__noreturn__));
|
__THROW __attribute__ ((__noreturn__));
|
||||||
|
|
||||||
/* Likewise, but prints the error text for ERRNUM. */
|
/* Likewise, but prints the error text for ERRNUM. */
|
||||||
extern void __assert_perror_fail (int __errnum, __const char *__file,
|
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)
|
__const char *__function)
|
||||||
__THROW __attribute__ ((__noreturn__));
|
__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
|
#if !defined NOT_IN_libc || defined IS_IN_rtld
|
||||||
hidden_proto (__assert_fail)
|
hidden_proto (__assert_fail)
|
||||||
hidden_proto (__assert_perror_fail)
|
hidden_proto (__assert_perror_fail)
|
||||||
|
|
|
@ -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)
|
# define __cxa_atexit(func, arg, d) INTUSE(__cxa_atexit) (func, arg, d)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void *__default_morecore (ptrdiff_t) __THROW;
|
extern void *__default_morecore (ptrdiff_t) __THROW;
|
||||||
libc_hidden_proto (__default_morecore)
|
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)
|
libc_hidden_proto (__abort_msg)
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef __Need_M_And_C
|
#undef __Need_M_And_C
|
||||||
|
|
||||||
#endif /* include/stdlib.h */
|
#endif /* include/stdlib.h */
|
||||||
|
|
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -37,7 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exported variable to locate abort message in core files etc. */
|
/* 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)
|
libc_hidden_def (__abort_msg)
|
||||||
|
|
||||||
/* We must avoid to run in circles. Therefore we remember how far we
|
/* We must avoid to run in circles. Therefore we remember how far we
|
||||||
|
|
|
@ -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.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.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)
|
if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total)
|
||||||
written = true;
|
written = true;
|
||||||
|
|
||||||
char *buf = do_abort ? malloc (total + 1) : NULL;
|
if (do_abort)
|
||||||
if (buf != NULL)
|
|
||||||
{
|
{
|
||||||
char *wp = buf;
|
total = ((total + 1 + GLRO(dl_pagesize) - 1)
|
||||||
for (int cnt = 0; cnt < nlist; ++cnt)
|
& ~(GLRO(dl_pagesize) - 1));
|
||||||
wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
|
struct abort_msg_s *buf = __mmap (NULL, total,
|
||||||
*wp = '\0';
|
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
|
/* We have to free the old buffer since the application might
|
||||||
catch the SIGABRT signal. */
|
catch the SIGABRT signal. */
|
||||||
char *old = atomic_exchange_acq (&__abort_msg, buf);
|
struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
|
||||||
free (old);
|
buf);
|
||||||
|
if (old != NULL)
|
||||||
|
__munmap (old, old->size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
|
|
||||||
|
@ -134,18 +136,28 @@ __libc_message (int do_abort, const char *fmt, ...)
|
||||||
if (cnt == total)
|
if (cnt == total)
|
||||||
written = true;
|
written = true;
|
||||||
|
|
||||||
char *buf = do_abort ? malloc (total + 1) : NULL;
|
if (do_abort)
|
||||||
if (buf != NULL)
|
|
||||||
{
|
{
|
||||||
char *wp = buf;
|
total = ((total + 1 + GLRO(dl_pagesize) - 1)
|
||||||
for (int cnt = 0; cnt < nlist; ++cnt)
|
& ~(GLRO(dl_pagesize) - 1));
|
||||||
wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
|
struct abort_msg_s *buf = __mmap (NULL, total,
|
||||||
*wp = '\0';
|
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
|
/* We have to free the old buffer since the application might
|
||||||
catch the SIGABRT signal. */
|
catch the SIGABRT signal. */
|
||||||
char *old = atomic_exchange_acq (&__abort_msg, buf);
|
struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
|
||||||
free (old);
|
buf);
|
||||||
|
if (old != NULL)
|
||||||
|
__munmap (old, old->size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue