emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r109879: Give more-useful info on a f


From: Paul Eggert
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109879: Give more-useful info on a fatal error (Bug#12328).
Date: Tue, 04 Sep 2012 11:29:04 -0700
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109879
fixes bug: http://debbugs.gnu.org/12328
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Tue 2012-09-04 11:29:04 -0700
message:
  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.
modified:
  doc/emacs/ChangeLog
  doc/emacs/emacs.texi
  doc/emacs/trouble.texi
  etc/ChangeLog
  etc/NEWS
  src/ChangeLog
  src/alloc.c
  src/emacs.c
  src/lisp.h
  src/sysdep.c
=== modified file 'doc/emacs/ChangeLog'
--- a/doc/emacs/ChangeLog       2012-08-28 16:01:59 +0000
+++ b/doc/emacs/ChangeLog       2012-09-04 18:29:04 +0000
@@ -1,3 +1,8 @@
+2012-09-04  Paul Eggert  <address@hidden>
+
+       Give more-useful info on a fatal error (Bug#12328).
+       * trouble.texi (Crashing): New section, documenting this.
+
 2012-08-24  Michael Albinus  <address@hidden>
 
        * cmdargs.texi (General Variables): Setting

=== modified file 'doc/emacs/emacs.texi'
--- a/doc/emacs/emacs.texi      2012-08-07 03:31:53 +0000
+++ b/doc/emacs/emacs.texi      2012-09-04 18:29:04 +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.
 
@@ -1320,7 +1321,7 @@
 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}.
 

=== modified file 'doc/emacs/trouble.texi'
--- a/doc/emacs/trouble.texi    2012-05-27 01:25:06 +0000
+++ b/doc/emacs/trouble.texi    2012-09-04 18:29:04 +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.
 
address@hidden Crashing
address@hidden 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
address@hidden  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:
+
address@hidden
+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]
+...
address@hidden example
+
address@hidden
+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'
--- a/etc/ChangeLog     2012-09-01 01:04:26 +0000
+++ b/etc/ChangeLog     2012-09-04 18:29:04 +0000
@@ -1,3 +1,8 @@
+2012-09-04  Paul Eggert  <address@hidden>
+
+       Give more-useful info on a fatal error (Bug#12328).
+       * NEWS: Document the change.
+
 2012-09-01  Paul Eggert  <address@hidden>
 
        Better seeds for (random).

=== modified file 'etc/NEWS'
--- a/etc/NEWS  2012-09-04 17:40:25 +0000
+++ b/etc/NEWS  2012-09-04 18:29:04 +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'
--- a/src/ChangeLog     2012-09-04 17:40:25 +0000
+++ b/src/ChangeLog     2012-09-04 18:29:04 +0000
@@ -1,3 +1,22 @@
+2012-09-04  Paul Eggert  <address@hidden>
+
+       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  <address@hidden>
 
        * lread.c (readevalloop): Call internal-macroexpand-for-load to perform

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2012-09-04 17:34:54 +0000
+++ b/src/alloc.c       2012-09-04 18:29:04 +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'
--- a/src/emacs.c       2012-09-04 17:34:54 +0000
+++ b/src/emacs.c       2012-09-04 18:29:04 +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, 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'
--- a/src/lisp.h        2012-09-04 17:34:54 +0000
+++ b/src/lisp.h        2012-09-04 18:29:04 +0000
@@ -3266,6 +3266,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);
@@ -3412,6 +3413,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'
--- a/src/sysdep.c      2012-09-04 17:34:54 +0000
+++ b/src/sysdep.c      2012-09-04 18:29:04 +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 via email to

[Prev in Thread] Current Thread [Next in Thread]