Commit cf29dd84 authored by Paul Eggert's avatar Paul Eggert

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.
parent 972debf2
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
......
......@@ -1136,6 +1136,7 @@ Dealing with Emacs Trouble
* 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.
......@@ -1320,7 +1321,7 @@ when you get it, not just free for the manufacturer.
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}.
......
......@@ -149,6 +149,7 @@ Emacs.
* 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
......@@ -277,6 +278,44 @@ editing in the same Emacs session.
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).
......
......@@ -97,6 +97,11 @@ machines. Other functions that use this format, such as
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
......
......@@ -6685,21 +6685,14 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
#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
......
......@@ -298,6 +298,14 @@ void
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);
......@@ -312,6 +320,7 @@ fatal_error_signal (int sig)
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.
......@@ -323,6 +332,9 @@ fatal_error_signal (int sig)
#endif
kill (getpid (), fatal_error_code);
/* This shouldn't be executed, but it prevents a warning. */
exit (1);
}
#ifdef SIGDANGER
......@@ -1992,7 +2004,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
{
reset_all_sys_modes ();
if (sig && sig != SIGTERM)
fprintf (stderr, "Fatal error (%d)", sig);
fprintf (stderr, "Fatal error %d: %s", sig, strsignal (sig));
}
}
#else
......
......@@ -3266,6 +3266,7 @@ extern Lisp_Object Qfile_name_handler_alist;
#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);
......@@ -3412,6 +3413,7 @@ extern int set_window_size (int, int, int);
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);
......
......@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define SYSTIME_INLINE EXTERN_INLINE
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
......@@ -1856,12 +1857,30 @@ snprintf (char *buf, size_t bufsize, char const *format, ...)
}
#endif
/* 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));
}
#ifndef HAVE_NTGUI
/* Using emacs_abort lets GDB return from a breakpoint here. */
void
emacs_abort (void)
{
abort ();
fatal_error_backtrace (SIGABRT, 10);
}
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment