[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r110769: Implement backtrace output f
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r110769: Implement backtrace output for fatal errors on MS-Windows. |
Date: |
Fri, 02 Nov 2012 16:00:45 +0200 |
User-agent: |
Bazaar (2.5.0) |
------------------------------------------------------------
revno: 110769
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Fri 2012-11-02 16:00:45 +0200
message:
Implement backtrace output for fatal errors on MS-Windows.
src/w32fns.c (CaptureStackBackTrace_proc): New typedef.
(BACKTRACE_LIMIT_MAX): New macro.
(w32_backtrace): New function.
(emacs_abort): Use w32_backtrace when the user chooses not to
attach a debugger. Update the text of the abort dialog.
modified:
src/ChangeLog
src/w32fns.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2012-11-02 10:34:26 +0000
+++ b/src/ChangeLog 2012-11-02 14:00:45 +0000
@@ -1,3 +1,12 @@
+2012-11-02 Eli Zaretskii <address@hidden>
+
+ Implement backtrace output for fatal errors on MS-Windows.
+ * w32fns.c (CaptureStackBackTrace_proc): New typedef.
+ (BACKTRACE_LIMIT_MAX): New macro.
+ (w32_backtrace): New function.
+ (emacs_abort): Use w32_backtrace when the user chooses not to
+ attach a debugger. Update the text of the abort dialog.
+
2012-11-02 Dmitry Antipov <address@hidden>
Window-related stuff cleanup here and there.
=== modified file 'src/w32fns.c'
--- a/src/w32fns.c 2012-10-26 09:46:46 +0000
+++ b/src/w32fns.c 2012-11-02 14:00:45 +0000
@@ -26,6 +26,7 @@
#include <limits.h>
#include <errno.h>
#include <math.h>
+#include <fcntl.h>
#include "lisp.h"
#include "w32term.h"
@@ -7697,6 +7698,30 @@
syms_of_w32uniscribe ();
}
+typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *,
+ PULONG);
+
+#define BACKTRACE_LIMIT_MAX 62
+
+int
+w32_backtrace (void **buffer, int limit)
+{
+ static CaptureStackBackTrace_proc s_pfn_CaptureStackBackTrace = NULL;
+ HMODULE hm_kernel32 = NULL;
+
+ if (!s_pfn_CaptureStackBackTrace)
+ {
+ hm_kernel32 = LoadLibrary ("Kernel32.dll");
+ s_pfn_CaptureStackBackTrace =
+ (CaptureStackBackTrace_proc) GetProcAddress (hm_kernel32,
+
"RtlCaptureStackBackTrace");
+ }
+ if (s_pfn_CaptureStackBackTrace)
+ return s_pfn_CaptureStackBackTrace (0, min (BACKTRACE_LIMIT_MAX, limit),
+ buffer, NULL);
+ return 0;
+}
+
void
emacs_abort (void)
{
@@ -7704,7 +7729,10 @@
button = MessageBox (NULL,
"A fatal error has occurred!\n\n"
"Would you like to attach a debugger?\n\n"
- "Select YES to debug, NO to abort Emacs"
+ "Select:\n"
+ "YES -- to debug Emacs, or\n"
+ "NO -- to abort Emacs and produce a backtrace\n"
+ " (emacs_backtrace.txt in current directory)."
#if __GNUC__
"\n\n(type \"gdb -p <emacs-PID>\" and\n"
"\"continue\" inside GDB before clicking YES.)"
@@ -7719,7 +7747,52 @@
exit (2); /* tell the compiler we will never return */
case IDNO:
default:
- abort ();
- break;
+ {
+ void *stack[BACKTRACE_LIMIT_MAX + 1];
+ int i = w32_backtrace (stack, BACKTRACE_LIMIT_MAX + 1);
+
+ if (i)
+ {
+ HANDLE errout = GetStdHandle (STD_ERROR_HANDLE);
+ int stderr_fd = -1, errfile_fd = -1;
+ int j;
+
+ if (errout && errout != INVALID_HANDLE_VALUE)
+ stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND |
O_BINARY);
+ if (stderr_fd >= 0)
+ write (stderr_fd, "\r\nBacktrace:\r\n", 14);
+ errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT |
O_BINARY, S_IREAD | S_IWRITE);
+ if (errfile_fd >= 0)
+ {
+ lseek (errfile_fd, 0L, SEEK_END);
+ write (errfile_fd, "\r\nBacktrace:\r\n", 14);
+ }
+
+ for (j = 0; j < i; j++)
+ {
+ char buf[INT_BUFSIZE_BOUND (void *)];
+
+ /* stack[] gives the return addresses, whereas we want
+ the address of the call, so decrease each address
+ by approximate size of 1 CALL instruction. */
+ sprintf (buf, "0x%p\r\n", stack[j] - sizeof(void *));
+ if (stderr_fd >= 0)
+ write (stderr_fd, buf, strlen (buf));
+ if (errfile_fd >= 0)
+ write (errfile_fd, buf, strlen (buf));
+ }
+ if (i == BACKTRACE_LIMIT_MAX)
+ {
+ if (stderr_fd >= 0)
+ write (stderr_fd, "...\r\n", 5);
+ if (errfile_fd >= 0)
+ write (errfile_fd, "...\r\n", 5);
+ }
+ if (errfile_fd >= 0)
+ close (errfile_fd);
+ }
+ abort ();
+ break;
+ }
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r110769: Implement backtrace output for fatal errors on MS-Windows.,
Eli Zaretskii <=