* 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.
+2012-09-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Give more-useful info on a fatal error (Bug#12328).
+ * trouble.texi (Crashing): New section, documenting this.
+
2012-08-24 Michael Albinus <michael.albinus@gmx.de>
* cmdargs.texi (General Variables): Setting
* Screen Garbled:: Garbage on the screen.
* Text Garbled:: Garbage in the text.
* Memory Full:: How to cope when you run out of memory.
+* Crashing:: What Emacs does when it crashes.
* After a Crash:: Recovering editing in an Emacs session that crashed.
* Emergency Escape:: What to do if Emacs stops responding.
If you find GNU Emacs useful, please @strong{send a donation} to the
Free Software Foundation to support our work. Donations to the Free
Software Foundation are tax deductible in the US. If you use GNU Emacs
-at your workplace, please suggest that the company make a donation.
+at your workplace, please suggest that the company make a donation.
For more information on how you can help, see
@url{http://www.gnu.org/help/help.html}.
* Screen Garbled:: Garbage on the screen.
* Text Garbled:: Garbage in the text.
* Memory Full:: How to cope when you run out of memory.
+* Crashing:: What Emacs does when it crashes.
* After a Crash:: Recovering editing in an Emacs session that crashed.
* Emergency Escape:: What to do if Emacs stops responding.
@end menu
out of memory, because the buffer menu needs a fair amount of memory
itself, and the reserve supply may not be enough.
+@node Crashing
+@subsection When Emacs Crashes
+
+ Emacs is not supposed to crash, but if it does, before it exits it
+reports some information about the crash to the standard error stream
+@code{stderr}. This report may be useful to someone who later debugs
+the same version of Emacs on the same platform. The format of this
+report depends on the platform, and some platforms support backtraces.
+Here is an example, generated on x86-64 GNU/Linux with version 2.15 of
+the GNU C Library:
+
+@example
+Fatal error 11: Segmentation fault
+Backtrace:
+emacs[0x5094e4]
+emacs[0x4ed3e6]
+emacs[0x4ed504]
+/lib64/libpthread.so.0[0x375220efe0]
+/lib64/libpthread.so.0(read+0xe)[0x375220e08e]
+emacs[0x509af6]
+emacs[0x5acc26]
+emacs[0x5adbfb]
+emacs[0x56566b]
+emacs[0x59bac3]
+emacs[0x565151]
+...
+@end example
+
+@noindent
+The number @samp{11} is the system signal number that corresponds to
+the problem, a segmentation fault here. The hexadecimal program
+addresses can be useful in debugging sessions. For example, the GDB
+command @samp{list *0x509af6} prints the source-code lines
+corresponding to the @samp{emacs[0x509af6]} entry in the backtrace.
+
+The three dots at the end indicate that Emacs suppressed further
+backtrace entries, in the interest of brevity.
+
@node After a Crash
@subsection Recovery After a Crash
+2012-09-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Give more-useful info on a fatal error (Bug#12328).
+ * NEWS: Document the change.
+
2012-09-01 Paul Eggert <eggert@cs.ucla.edu>
Better seeds for (random).
file-attributes and format-time-string, have been changed accordingly.
Old-format time stamps are still accepted.
+** Emacs now generates backtraces on fatal errors.
+On encountering a fatal error, Emacs now outputs a textual description
+of the fatal signal, and a short backtrace on platforms like glibc
+that support backtraces.
+
** New functions `system-users', `system-groups' return lists of the user
name, group names known to the system (where possible).
+2012-09-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ Give more-useful info on a fatal error (Bug#12328).
+ * alloc.c [ENABLE_CHECKING]: Do not include <execinfo.h>.
+ (die) [ENABLE_CHECKING]: Call fatal_error_backtrace instead
+ of doing the work ourselves.
+ * 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.
+ * lisp.h (fatal_error_backtrace, emacs_backtrace): New decls.
+ * 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.
+
2012-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
* lread.c (readevalloop): Call internal-macroexpand-for-load to perform
#ifdef ENABLE_CHECKING
-# include <execinfo.h>
-
bool suppress_checking;
void
die (const char *msg, const char *file, int line)
{
- enum { NPOINTERS_MAX = 500 };
- void *buffer[NPOINTERS_MAX];
- int npointers;
fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n",
file, line, msg);
- npointers = backtrace (buffer, NPOINTERS_MAX);
- backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
- emacs_abort ();
+ fatal_error_backtrace (SIGABRT, INT_MAX);
}
#endif
\f
fatal_error_signal (int sig)
{
SIGNAL_THREAD_CHECK (sig);
+ fatal_error_backtrace (sig, 10);
+}
+
+/* Report a fatal error due to signal SIG, output a backtrace of at
+ most BACKTRACE_LIMIT lines, and exit. */
+_Noreturn void
+fatal_error_backtrace (int sig, int backtrace_limit)
+{
fatal_error_code = sig;
signal (sig, SIG_DFL);
Fkill_emacs (make_number (sig));
shut_down_emacs (sig, Qnil);
+ emacs_backtrace (backtrace_limit);
}
/* Signal the same code; this time it will really be fatal.
#endif
kill (getpid (), fatal_error_code);
+
+ /* This shouldn't be executed, but it prevents a warning. */
+ exit (1);
}
#ifdef SIGDANGER
{
reset_all_sys_modes ();
if (sig && sig != SIGTERM)
- fprintf (stderr, "Fatal error (%d)", sig);
+ fprintf (stderr, "Fatal error %d: %s", sig, strsignal (sig));
}
}
#else
#ifdef FLOAT_CATCH_SIGILL
extern void fatal_error_signal (int);
#endif
+extern _Noreturn void fatal_error_backtrace (int, int);
extern Lisp_Object Qkill_emacs;
#if HAVE_SETLOCALE
void fixup_locale (void);
extern EMACS_INT get_random (void);
extern void seed_random (void *, ptrdiff_t);
extern void init_random (void);
+extern void emacs_backtrace (int);
extern _Noreturn void emacs_abort (void) NO_INLINE;
extern int emacs_open (const char *, int, int);
extern int emacs_close (int);
#define SYSTIME_INLINE EXTERN_INLINE
+#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
}
#endif
\f
+/* If a backtrace is available, output the top lines of it to stderr.
+ Do not output more than BACKTRACE_LIMIT or BACKTRACE_LIMIT_MAX lines.
+ This function may be called from a signal handler, so it should
+ not invoke async-unsafe functions like malloc. */
+void
+emacs_backtrace (int backtrace_limit)
+{
+ enum { BACKTRACE_LIMIT_MAX = 500 };
+ void *buffer[BACKTRACE_LIMIT_MAX + 1];
+ int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX);
+ int npointers = backtrace (buffer, bounded_limit + 1);
+ if (npointers)
+ ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
+ backtrace_symbols_fd (buffer, bounded_limit, STDERR_FILENO);
+ if (bounded_limit < npointers)
+ ignore_value (write (STDERR_FILENO, "...\n", 4));
+}
+\f
#ifndef HAVE_NTGUI
/* Using emacs_abort lets GDB return from a breakpoint here. */
void
emacs_abort (void)
{
- abort ();
+ fatal_error_backtrace (SIGABRT, 10);
}
#endif