1 2011-05-15 Ulrich Drepper <drepper@gmail.com>
4 * include/stdlib.h: Move include protection to the right place.
5 Define abort_msg_s. Declare __abort_msg with it.
6 * stdlib/abort.c (__abort_msg): Adjust type.
7 * assert/assert.c (__assert_fail_base): New function. Majority
8 of code from __assert_fail. Allocate memory for __abort_msg with
10 (__assert_fail): Now call __assert_fail_base.
11 * assert/assert-perr.c: Remove bulk of implementation. Use
13 * include/assert.hL Declare __assert_fail_base.
14 * sysdeps/posix/libc_fatal.c: Allocate memory for __abort_msg with
16 * sysdeps/unix/sysv/linux/libc_fatal.c: Likewise.
18 Index: glibc-2.12-2-gc4ccff1/assert/assert-perr.c
19 ===================================================================
20 --- glibc-2.12-2-gc4ccff1.orig/assert/assert-perr.c
21 +++ glibc-2.12-2-gc4ccff1/assert/assert-perr.c
35 -extern const char *__progname;
39 -# include <libio/iolibio.h>
40 -# define fflush(s) INTUSE(_IO_fflush) (s)
43 /* This function, when passed an error number, a filename, and a line
44 number, prints a message on the standard error stream of the form:
45 - a.c:10: foobar: Unexpected error: Computer bought the farm
46 + a.c:10: foobar: Unexpected error: Computer bought the farm
47 It then aborts program execution via a call to `abort'. */
49 -#ifdef FATAL_PREPARE_INCLUDE
50 -# include FATAL_PREPARE_INCLUDE
54 __assert_perror_fail (int errnum,
55 const char *file, unsigned int line,
65 - if (__asprintf (&buf, _("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
66 - __progname, __progname[0] ? ": " : "",
68 - function ? function : "", function ? ": " : "",
69 - __strerror_r (errnum, errbuf, sizeof errbuf)) >= 0)
71 - /* Print the message. */
72 - (void) __fxprintf (NULL, "%s", buf);
73 - (void) fflush (stderr);
75 - /* We have to free the old buffer since the application might
76 - catch the SIGABRT signal. */
77 - char *old = atomic_exchange_acq (&__abort_msg, buf);
82 - /* At least print a minimal message. */
83 - static const char errstr[] = "Unexpected error.\n";
84 - __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
88 + char *e = __strerror_r (errnum, errbuf, sizeof errbuf);
89 + __assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
90 + e, file, line, function);
92 libc_hidden_def (__assert_perror_fail)
93 Index: glibc-2.12-2-gc4ccff1/assert/assert.c
94 ===================================================================
95 --- glibc-2.12-2-gc4ccff1.orig/assert/assert.c
96 +++ glibc-2.12-2-gc4ccff1/assert/assert.c
101 +#include <ldsodefs.h>
107 +#include <sys/mman.h>
110 extern const char *__progname;
111 @@ -45,31 +47,44 @@ extern const char *__progname;
115 -#undef __assert_fail
117 -__assert_fail (const char *assertion, const char *file, unsigned int line,
118 - const char *function)
119 +__assert_fail_base (const char *fmt, const char *assertion, const char *file,
120 + unsigned int line, const char *function)
129 - if (__asprintf (&buf, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
131 + if (__asprintf (&str, fmt,
132 __progname, __progname[0] ? ": " : "",
134 function ? function : "", function ? ": " : "",
136 + assertion, &total) >= 0)
138 /* Print the message. */
139 - (void) __fxprintf (NULL, "%s", buf);
140 + (void) __fxprintf (NULL, "%s", str);
141 (void) fflush (stderr);
143 - /* We have to free the old buffer since the application might
144 - catch the SIGABRT signal. */
145 - char *old = atomic_exchange_acq (&__abort_msg, buf);
147 + total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
148 + struct abort_msg_s *buf = __mmap (NULL, total, PROT_READ | PROT_WRITE,
149 + MAP_ANON | MAP_PRIVATE, -1, 0);
150 + if (__builtin_expect (buf != MAP_FAILED, 1))
153 + strcpy (buf->msg, str);
155 + /* We have to free the old buffer since the application might
156 + catch the SIGABRT signal. */
157 + struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg, buf);
160 + __munmap (old, old->size);
167 @@ -80,4 +95,14 @@ __assert_fail (const char *assertion, co
173 +#undef __assert_fail
175 +__assert_fail (const char *assertion, const char *file, unsigned int line,
176 + const char *function)
178 + __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
179 + assertion, file, line, function);
181 hidden_def(__assert_fail)
182 Index: glibc-2.12-2-gc4ccff1/include/assert.h
183 ===================================================================
184 --- glibc-2.12-2-gc4ccff1.orig/include/assert.h
185 +++ glibc-2.12-2-gc4ccff1/include/assert.h
186 @@ -13,6 +13,12 @@ extern void __assert_perror_fail (int __
187 __const char *__function)
188 __THROW __attribute__ ((__noreturn__));
190 +/* The real implementation of the two functions above. */
191 +extern void __assert_fail_base (const char *fmt, const char *assertion,
192 + const char *file, unsigned int line,
193 + const char *function)
194 + __THROW __attribute__ ((__noreturn__));
196 #if !defined NOT_IN_libc || defined IS_IN_rtld
197 hidden_proto (__assert_fail)
198 hidden_proto (__assert_perror_fail)
199 Index: glibc-2.12-2-gc4ccff1/include/stdlib.h
200 ===================================================================
201 --- glibc-2.12-2-gc4ccff1.orig/include/stdlib.h
202 +++ glibc-2.12-2-gc4ccff1/include/stdlib.h
203 @@ -223,16 +223,21 @@ extern int __qfcvt_r (long double __valu
204 # define __cxa_atexit(func, arg, d) INTUSE(__cxa_atexit) (func, arg, d)
209 extern void *__default_morecore (ptrdiff_t) __THROW;
210 libc_hidden_proto (__default_morecore)
212 -extern char *__abort_msg;
218 +extern struct abort_msg_s *__abort_msg;
219 libc_hidden_proto (__abort_msg)
225 #undef __Need_M_And_C
227 #endif /* include/stdlib.h */
228 Index: glibc-2.12-2-gc4ccff1/stdlib/abort.c
229 ===================================================================
230 --- glibc-2.12-2-gc4ccff1.orig/stdlib/abort.c
231 +++ glibc-2.12-2-gc4ccff1/stdlib/abort.c
235 /* Exported variable to locate abort message in core files etc. */
236 -char *__abort_msg __attribute__ ((nocommon));
237 +struct abort_msg_s *__abort_msg __attribute__ ((nocommon));
238 libc_hidden_def (__abort_msg)
240 /* We must avoid to run in circles. Therefore we remember how far we
241 Index: glibc-2.12-2-gc4ccff1/sysdeps/posix/libc_fatal.c
242 ===================================================================
243 --- glibc-2.12-2-gc4ccff1.orig/sysdeps/posix/libc_fatal.c
244 +++ glibc-2.12-2-gc4ccff1/sysdeps/posix/libc_fatal.c
249 +#include <ldsodefs.h>
253 @@ -125,18 +126,28 @@ __libc_message (int do_abort, const char
254 if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total)
257 - char *buf = do_abort ? malloc (total + 1) : NULL;
262 - for (int cnt = 0; cnt < nlist; ++cnt)
263 - wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
266 - /* We have to free the old buffer since the application might
267 - catch the SIGABRT signal. */
268 - char *old = atomic_exchange_acq (&__abort_msg, buf);
270 + total = ((total + 1 + GLRO(dl_pagesize) - 1)
271 + & ~(GLRO(dl_pagesize) - 1));
272 + struct abort_msg_s *buf = __mmap (NULL, total,
273 + PROT_READ | PROT_WRITE,
274 + MAP_ANON | MAP_PRIVATE, -1, 0);
275 + if (buf != MAP_FAILED)
278 + char *wp = buf->msg;
279 + for (int cnt = 0; cnt < nlist; ++cnt)
280 + wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
283 + /* We have to free the old buffer since the application might
284 + catch the SIGABRT signal. */
285 + struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
288 + __munmap (old, old->size);
293 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/libc_fatal.c
294 ===================================================================
295 --- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/libc_fatal.c
296 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/libc_fatal.c
301 +#include <ldsodefs.h>
309 +#include <sys/mman.h>
310 #include <sys/syslog.h>
311 #include <execinfo.h>
313 @@ -134,18 +136,28 @@ __libc_message (int do_abort, const char
317 - char *buf = do_abort ? malloc (total + 1) : NULL;
322 - for (int cnt = 0; cnt < nlist; ++cnt)
323 - wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
326 - /* We have to free the old buffer since the application might
327 - catch the SIGABRT signal. */
328 - char *old = atomic_exchange_acq (&__abort_msg, buf);
330 + total = ((total + 1 + GLRO(dl_pagesize) - 1)
331 + & ~(GLRO(dl_pagesize) - 1));
332 + struct abort_msg_s *buf = __mmap (NULL, total,
333 + PROT_READ | PROT_WRITE,
334 + MAP_ANON | MAP_PRIVATE, -1, 0);
335 + if (__builtin_expect (buf != MAP_FAILED, 1))
338 + char *wp = buf->msg;
339 + for (int cnt = 0; cnt < nlist; ++cnt)
340 + wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
343 + /* We have to free the old buffer since the application might
344 + catch the SIGABRT signal. */
345 + struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
348 + __munmap (old, old->size);