GNU bug report logs - #12328
Give more-useful info on a fatal error.

Previous Next

Package: emacs;

Reported by: Paul Eggert <eggert <at> cs.ucla.edu>

Date: Sun, 2 Sep 2012 00:29:02 UTC

Severity: normal

Tags: patch

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 12328 in the body.
You can then email your comments to 12328 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#12328; Package emacs. (Sun, 02 Sep 2012 00:29:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Paul Eggert <eggert <at> cs.ucla.edu>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 02 Sep 2012 00:29:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: bug-gnu-emacs <at> gnu.org
Cc: Juanma Barranquero <lekktu <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>
Subject: Give more-useful info on a fatal error.
Date: Sat, 01 Sep 2012 17:26:49 -0700
Tags: patch

Here's a patch I'm planning to install into Emacs, to improve the
quality of its output after it crashes, by outputting a backtrace and
a text string describing the fatal error.  This patch assumes the
patch I submitted for Bug#12316; see the updated version in
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12316#20>.

I don't know of any extra implications for Windows due to this
patch, but just in case I'm CC'ing this to Eli and Juanma.

=== modified file 'doc/emacs/ChangeLog'
--- doc/emacs/ChangeLog	2012-08-28 16:01:59 +0000
+++ doc/emacs/ChangeLog	2012-09-01 23:55:29 +0000
@@ -1,3 +1,8 @@
+2012-09-01  Paul Eggert  <eggert <at> cs.ucla.edu>
+
+	Give more-useful info on a fatal error.
+	* trouble.texi (Crashing): New section, documenting this.
+
 2012-08-24  Michael Albinus  <michael.albinus <at> gmx.de>
 
 	* cmdargs.texi (General Variables): Setting

=== modified file 'doc/emacs/emacs.texi'
--- doc/emacs/emacs.texi	2012-08-07 03:31:53 +0000
+++ doc/emacs/emacs.texi	2012-09-01 23:55:29 +0000
@@ -1136,6 +1136,7 @@
 * 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.
 

=== modified file 'doc/emacs/trouble.texi'
--- doc/emacs/trouble.texi	2012-05-27 01:25:06 +0000
+++ doc/emacs/trouble.texi	2012-09-01 23:55:29 +0000
@@ -149,6 +149,7 @@
 * 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 @@
 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
 

=== modified file 'etc/ChangeLog'
--- etc/ChangeLog	2012-09-01 01:04:26 +0000
+++ etc/ChangeLog	2012-09-01 23:55:29 +0000
@@ -1,5 +1,8 @@
 2012-09-01  Paul Eggert  <eggert <at> cs.ucla.edu>
 
+	Give more-useful info on a fatal error.
+	* NEWS: Document the change.
+
 	Better seeds for (random).
 	* NEWS: Document new behavior of (random), (random "string").
 

=== modified file 'etc/NEWS'
--- etc/NEWS	2012-09-01 01:04:26 +0000
+++ etc/NEWS	2012-09-01 23:55:29 +0000
@@ -97,6 +97,11 @@
 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).
 

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2012-09-01 22:55:39 +0000
+++ src/ChangeLog	2012-09-01 23:55:29 +0000
@@ -1,5 +1,22 @@
 2012-09-01  Paul Eggert  <eggert <at> cs.ucla.edu>
 
+	Give more-useful info on a fatal error.
+	* 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.
+
 	Simplify redefinition of 'abort' (Bug#12316).
 	Do not try to redefine the 'abort' function.  Instead, redo
 	the code so that it calls 'emacs_abort' rather than 'abort'.

=== modified file 'src/alloc.c'
--- src/alloc.c	2012-08-31 16:21:56 +0000
+++ src/alloc.c	2012-09-01 13:44:44 +0000
@@ -6685,21 +6685,14 @@
 
 #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
 

=== modified file 'src/emacs.c'
--- src/emacs.c	2012-09-01 13:39:22 +0000
+++ src/emacs.c	2012-09-01 13:44:44 +0000
@@ -298,6 +298,14 @@
 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 @@
         Fkill_emacs (make_number (sig));
 
       shut_down_emacs (sig, 0, Qnil);
+      emacs_backtrace (backtrace_limit);
     }
 
   /* Signal the same code; this time it will really be fatal.
@@ -323,6 +332,9 @@
 #endif
 
   kill (getpid (), fatal_error_code);
+
+  /* This shouldn't be executed, but it prevents a warning.  */
+  exit (1);
 }
 
 #ifdef SIGDANGER
@@ -1992,7 +2004,7 @@
       {
 	reset_all_sys_modes ();
 	if (sig && sig != SIGTERM)
-	  fprintf (stderr, "Fatal error (%d)", sig);
+	  fprintf (stderr, "Fatal error %d: %s", sig, strsignal (sig));
       }
   }
 #else

=== modified file 'src/lisp.h'
--- src/lisp.h	2012-09-01 01:32:53 +0000
+++ src/lisp.h	2012-09-01 13:44:44 +0000
@@ -3265,6 +3265,7 @@
 #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);
@@ -3407,6 +3408,7 @@
 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);

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2012-09-01 01:32:53 +0000
+++ src/sysdep.c	2012-09-01 23:55:29 +0000
@@ -21,6 +21,7 @@
 
 #define SYSTIME_INLINE EXTERN_INLINE
 
+#include <execinfo.h>
 #include <signal.h>
 #include <stdio.h>
 #include <setjmp.h>
@@ -1856,12 +1857,30 @@
 }
 #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
 




Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Tue, 04 Sep 2012 18:31:02 GMT) Full text and rfc822 format available.

Notification sent to Paul Eggert <eggert <at> cs.ucla.edu>:
bug acknowledged by developer. (Tue, 04 Sep 2012 18:31:02 GMT) Full text and rfc822 format available.

Message #10 received at 12328-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: 12328-done <at> debbugs.gnu.org
Cc: Juanma Barranquero <lekktu <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: Give more-useful info on a fatal error.
Date: Tue, 04 Sep 2012 11:30:38 -0700
I installed this patch into the trunk as bzr 109879
and am marking it as done.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 03 Oct 2012 11:24:02 GMT) Full text and rfc822 format available.

This bug report was last modified 11 years and 230 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.