aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2012-09-04 11:29:04 -0700
committerPaul Eggert2012-09-04 11:29:04 -0700
commitcf29dd84d205e1c78fed5d1ea0006a382658598c (patch)
tree7e6806fdd94ef53cda78db6b29a4df0276408eb4
parent972debf2e7381b4fd2c70f9c1fd585d8bd137917 (diff)
downloademacs-cf29dd84d205e1c78fed5d1ea0006a382658598c.tar.gz
emacs-cf29dd84d205e1c78fed5d1ea0006a382658598c.zip
Give more-useful info on a fatal error (Bug#12328).
* doc/emacs/trouble.texi (Crashing): New section, documenting this. * etc/NEWS: Document the change. * src/alloc.c [ENABLE_CHECKING]: Do not include <execinfo.h>. (die) [ENABLE_CHECKING]: Call fatal_error_backtrace instead of doing the work ourselves. * src/emacs.c (fatal_error_signal): Let fatal_error_backtrace do most of the work. (fatal_error_backtrace): New function, taken from the guts of the old fatal_error_signal, but with a new option to output a backtrace. (shut_down_emacs) [!DOS_NT]: Use strsignal to give more-useful info about the signal than just its number. * src/lisp.h (fatal_error_backtrace, emacs_backtrace): New decls. * src/sysdep.c: Include <execinfo.h> (emacs_backtrace): New function, taken partly from the previous code of the 'die' function. (emacs_abort): Call fatal_error_backtrace rather than abort.
-rw-r--r--doc/emacs/ChangeLog5
-rw-r--r--doc/emacs/emacs.texi3
-rw-r--r--doc/emacs/trouble.texi39
-rw-r--r--etc/ChangeLog5
-rw-r--r--etc/NEWS5
-rw-r--r--src/ChangeLog19
-rw-r--r--src/alloc.c9
-rw-r--r--src/emacs.c14
-rw-r--r--src/lisp.h2
-rw-r--r--src/sysdep.c21
10 files changed, 111 insertions, 11 deletions
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index a4f9985ad85..78f1d2c8e3b 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,8 @@
12012-09-04 Paul Eggert <eggert@cs.ucla.edu>
2
3 Give more-useful info on a fatal error (Bug#12328).
4 * trouble.texi (Crashing): New section, documenting this.
5
12012-08-24 Michael Albinus <michael.albinus@gmx.de> 62012-08-24 Michael Albinus <michael.albinus@gmx.de>
2 7
3 * cmdargs.texi (General Variables): Setting 8 * cmdargs.texi (General Variables): Setting
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index 6357aebc6ff..192a9a2bb28 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -1136,6 +1136,7 @@ Dealing with Emacs Trouble
1136* Screen Garbled:: Garbage on the screen. 1136* Screen Garbled:: Garbage on the screen.
1137* Text Garbled:: Garbage in the text. 1137* Text Garbled:: Garbage in the text.
1138* Memory Full:: How to cope when you run out of memory. 1138* Memory Full:: How to cope when you run out of memory.
1139* Crashing:: What Emacs does when it crashes.
1139* After a Crash:: Recovering editing in an Emacs session that crashed. 1140* After a Crash:: Recovering editing in an Emacs session that crashed.
1140* Emergency Escape:: What to do if Emacs stops responding. 1141* Emergency Escape:: What to do if Emacs stops responding.
1141 1142
@@ -1320,7 +1321,7 @@ when you get it, not just free for the manufacturer.
1320If you find GNU Emacs useful, please @strong{send a donation} to the 1321If you find GNU Emacs useful, please @strong{send a donation} to the
1321Free Software Foundation to support our work. Donations to the Free 1322Free Software Foundation to support our work. Donations to the Free
1322Software Foundation are tax deductible in the US. If you use GNU Emacs 1323Software Foundation are tax deductible in the US. If you use GNU Emacs
1323at your workplace, please suggest that the company make a donation. 1324at your workplace, please suggest that the company make a donation.
1324For more information on how you can help, see 1325For more information on how you can help, see
1325@url{http://www.gnu.org/help/help.html}. 1326@url{http://www.gnu.org/help/help.html}.
1326 1327
diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi
index 025185c583f..1806339e45d 100644
--- a/doc/emacs/trouble.texi
+++ b/doc/emacs/trouble.texi
@@ -149,6 +149,7 @@ Emacs.
149* Screen Garbled:: Garbage on the screen. 149* Screen Garbled:: Garbage on the screen.
150* Text Garbled:: Garbage in the text. 150* Text Garbled:: Garbage in the text.
151* Memory Full:: How to cope when you run out of memory. 151* Memory Full:: How to cope when you run out of memory.
152* Crashing:: What Emacs does when it crashes.
152* After a Crash:: Recovering editing in an Emacs session that crashed. 153* After a Crash:: Recovering editing in an Emacs session that crashed.
153* Emergency Escape:: What to do if Emacs stops responding. 154* Emergency Escape:: What to do if Emacs stops responding.
154@end menu 155@end menu
@@ -277,6 +278,44 @@ editing in the same Emacs session.
277out of memory, because the buffer menu needs a fair amount of memory 278out of memory, because the buffer menu needs a fair amount of memory
278itself, and the reserve supply may not be enough. 279itself, and the reserve supply may not be enough.
279 280
281@node Crashing
282@subsection When Emacs Crashes
283
284 Emacs is not supposed to crash, but if it does, before it exits it
285reports some information about the crash to the standard error stream
286@code{stderr}. This report may be useful to someone who later debugs
287the same version of Emacs on the same platform. The format of this
288report depends on the platform, and some platforms support backtraces.
289Here is an example, generated on x86-64 GNU/Linux with version 2.15 of
290the GNU C Library:
291
292@example
293Fatal error 11: Segmentation fault
294Backtrace:
295emacs[0x5094e4]
296emacs[0x4ed3e6]
297emacs[0x4ed504]
298/lib64/libpthread.so.0[0x375220efe0]
299/lib64/libpthread.so.0(read+0xe)[0x375220e08e]
300emacs[0x509af6]
301emacs[0x5acc26]
302emacs[0x5adbfb]
303emacs[0x56566b]
304emacs[0x59bac3]
305emacs[0x565151]
306...
307@end example
308
309@noindent
310The number @samp{11} is the system signal number that corresponds to
311the problem, a segmentation fault here. The hexadecimal program
312addresses can be useful in debugging sessions. For example, the GDB
313command @samp{list *0x509af6} prints the source-code lines
314corresponding to the @samp{emacs[0x509af6]} entry in the backtrace.
315
316The three dots at the end indicate that Emacs suppressed further
317backtrace entries, in the interest of brevity.
318
280@node After a Crash 319@node After a Crash
281@subsection Recovery After a Crash 320@subsection Recovery After a Crash
282 321
diff --git a/etc/ChangeLog b/etc/ChangeLog
index f3f244c7e39..aa788275256 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,8 @@
12012-09-04 Paul Eggert <eggert@cs.ucla.edu>
2
3 Give more-useful info on a fatal error (Bug#12328).
4 * NEWS: Document the change.
5
12012-09-01 Paul Eggert <eggert@cs.ucla.edu> 62012-09-01 Paul Eggert <eggert@cs.ucla.edu>
2 7
3 Better seeds for (random). 8 Better seeds for (random).
diff --git a/etc/NEWS b/etc/NEWS
index e4a612f6a9e..9a38deef05c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -97,6 +97,11 @@ machines. Other functions that use this format, such as
97file-attributes and format-time-string, have been changed accordingly. 97file-attributes and format-time-string, have been changed accordingly.
98Old-format time stamps are still accepted. 98Old-format time stamps are still accepted.
99 99
100** Emacs now generates backtraces on fatal errors.
101On encountering a fatal error, Emacs now outputs a textual description
102of the fatal signal, and a short backtrace on platforms like glibc
103that support backtraces.
104
100** New functions `system-users', `system-groups' return lists of the user 105** New functions `system-users', `system-groups' return lists of the user
101name, group names known to the system (where possible). 106name, group names known to the system (where possible).
102 107
diff --git a/src/ChangeLog b/src/ChangeLog
index b2634c4fdc4..ea3b3a92e01 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,22 @@
12012-09-04 Paul Eggert <eggert@cs.ucla.edu>
2
3 Give more-useful info on a fatal error (Bug#12328).
4 * alloc.c [ENABLE_CHECKING]: Do not include <execinfo.h>.
5 (die) [ENABLE_CHECKING]: Call fatal_error_backtrace instead
6 of doing the work ourselves.
7 * emacs.c (fatal_error_signal): Let fatal_error_backtrace
8 do most of the work.
9 (fatal_error_backtrace): New function, taken from the guts
10 of the old fatal_error_signal, but with a new option to output
11 a backtrace.
12 (shut_down_emacs) [!DOS_NT]: Use strsignal to give more-useful
13 info about the signal than just its number.
14 * lisp.h (fatal_error_backtrace, emacs_backtrace): New decls.
15 * sysdep.c: Include <execinfo.h>
16 (emacs_backtrace): New function, taken partly from the previous
17 code of the 'die' function.
18 (emacs_abort): Call fatal_error_backtrace rather than abort.
19
12012-09-04 Stefan Monnier <monnier@iro.umontreal.ca> 202012-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 21
3 * lread.c (readevalloop): Call internal-macroexpand-for-load to perform 22 * lread.c (readevalloop): Call internal-macroexpand-for-load to perform
diff --git a/src/alloc.c b/src/alloc.c
index 2a831cea62a..157d3a1d799 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6685,21 +6685,14 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
6685 6685
6686#ifdef ENABLE_CHECKING 6686#ifdef ENABLE_CHECKING
6687 6687
6688# include <execinfo.h>
6689
6690bool suppress_checking; 6688bool suppress_checking;
6691 6689
6692void 6690void
6693die (const char *msg, const char *file, int line) 6691die (const char *msg, const char *file, int line)
6694{ 6692{
6695 enum { NPOINTERS_MAX = 500 };
6696 void *buffer[NPOINTERS_MAX];
6697 int npointers;
6698 fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n", 6693 fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n",
6699 file, line, msg); 6694 file, line, msg);
6700 npointers = backtrace (buffer, NPOINTERS_MAX); 6695 fatal_error_backtrace (SIGABRT, INT_MAX);
6701 backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
6702 emacs_abort ();
6703} 6696}
6704#endif 6697#endif
6705 6698
diff --git a/src/emacs.c b/src/emacs.c
index b242cbf8844..18f249dc899 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -298,6 +298,14 @@ void
298fatal_error_signal (int sig) 298fatal_error_signal (int sig)
299{ 299{
300 SIGNAL_THREAD_CHECK (sig); 300 SIGNAL_THREAD_CHECK (sig);
301 fatal_error_backtrace (sig, 10);
302}
303
304/* Report a fatal error due to signal SIG, output a backtrace of at
305 most BACKTRACE_LIMIT lines, and exit. */
306_Noreturn void
307fatal_error_backtrace (int sig, int backtrace_limit)
308{
301 fatal_error_code = sig; 309 fatal_error_code = sig;
302 signal (sig, SIG_DFL); 310 signal (sig, SIG_DFL);
303 311
@@ -312,6 +320,7 @@ fatal_error_signal (int sig)
312 Fkill_emacs (make_number (sig)); 320 Fkill_emacs (make_number (sig));
313 321
314 shut_down_emacs (sig, Qnil); 322 shut_down_emacs (sig, Qnil);
323 emacs_backtrace (backtrace_limit);
315 } 324 }
316 325
317 /* Signal the same code; this time it will really be fatal. 326 /* Signal the same code; this time it will really be fatal.
@@ -323,6 +332,9 @@ fatal_error_signal (int sig)
323#endif 332#endif
324 333
325 kill (getpid (), fatal_error_code); 334 kill (getpid (), fatal_error_code);
335
336 /* This shouldn't be executed, but it prevents a warning. */
337 exit (1);
326} 338}
327 339
328#ifdef SIGDANGER 340#ifdef SIGDANGER
@@ -1992,7 +2004,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
1992 { 2004 {
1993 reset_all_sys_modes (); 2005 reset_all_sys_modes ();
1994 if (sig && sig != SIGTERM) 2006 if (sig && sig != SIGTERM)
1995 fprintf (stderr, "Fatal error (%d)", sig); 2007 fprintf (stderr, "Fatal error %d: %s", sig, strsignal (sig));
1996 } 2008 }
1997 } 2009 }
1998#else 2010#else
diff --git a/src/lisp.h b/src/lisp.h
index 0835795a26d..9ee9cd74b56 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3266,6 +3266,7 @@ extern Lisp_Object Qfile_name_handler_alist;
3266#ifdef FLOAT_CATCH_SIGILL 3266#ifdef FLOAT_CATCH_SIGILL
3267extern void fatal_error_signal (int); 3267extern void fatal_error_signal (int);
3268#endif 3268#endif
3269extern _Noreturn void fatal_error_backtrace (int, int);
3269extern Lisp_Object Qkill_emacs; 3270extern Lisp_Object Qkill_emacs;
3270#if HAVE_SETLOCALE 3271#if HAVE_SETLOCALE
3271void fixup_locale (void); 3272void fixup_locale (void);
@@ -3412,6 +3413,7 @@ extern int set_window_size (int, int, int);
3412extern EMACS_INT get_random (void); 3413extern EMACS_INT get_random (void);
3413extern void seed_random (void *, ptrdiff_t); 3414extern void seed_random (void *, ptrdiff_t);
3414extern void init_random (void); 3415extern void init_random (void);
3416extern void emacs_backtrace (int);
3415extern _Noreturn void emacs_abort (void) NO_INLINE; 3417extern _Noreturn void emacs_abort (void) NO_INLINE;
3416extern int emacs_open (const char *, int, int); 3418extern int emacs_open (const char *, int, int);
3417extern int emacs_close (int); 3419extern int emacs_close (int);
diff --git a/src/sysdep.c b/src/sysdep.c
index 78164a8f02a..1f4de194c64 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#define SYSTIME_INLINE EXTERN_INLINE 22#define SYSTIME_INLINE EXTERN_INLINE
23 23
24#include <execinfo.h>
24#include <signal.h> 25#include <signal.h>
25#include <stdio.h> 26#include <stdio.h>
26#include <setjmp.h> 27#include <setjmp.h>
@@ -1856,12 +1857,30 @@ snprintf (char *buf, size_t bufsize, char const *format, ...)
1856} 1857}
1857#endif 1858#endif
1858 1859
1860/* If a backtrace is available, output the top lines of it to stderr.
1861 Do not output more than BACKTRACE_LIMIT or BACKTRACE_LIMIT_MAX lines.
1862 This function may be called from a signal handler, so it should
1863 not invoke async-unsafe functions like malloc. */
1864void
1865emacs_backtrace (int backtrace_limit)
1866{
1867 enum { BACKTRACE_LIMIT_MAX = 500 };
1868 void *buffer[BACKTRACE_LIMIT_MAX + 1];
1869 int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX);
1870 int npointers = backtrace (buffer, bounded_limit + 1);
1871 if (npointers)
1872 ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
1873 backtrace_symbols_fd (buffer, bounded_limit, STDERR_FILENO);
1874 if (bounded_limit < npointers)
1875 ignore_value (write (STDERR_FILENO, "...\n", 4));
1876}
1877
1859#ifndef HAVE_NTGUI 1878#ifndef HAVE_NTGUI
1860/* Using emacs_abort lets GDB return from a breakpoint here. */ 1879/* Using emacs_abort lets GDB return from a breakpoint here. */
1861void 1880void
1862emacs_abort (void) 1881emacs_abort (void)
1863{ 1882{
1864 abort (); 1883 fatal_error_backtrace (SIGABRT, 10);
1865} 1884}
1866#endif 1885#endif
1867 1886