diff -r cf0cac11813d Modules/faulthandler.c --- a/Modules/faulthandler.c Thu Apr 02 09:50:06 2015 +0300 +++ b/Modules/faulthandler.c Thu Apr 02 10:14:13 2015 +0200 @@ -351,6 +351,27 @@ faulthandler_fatal_error(int signum) raise(signum); } +#ifdef MS_WINDOWS +extern void _Py_dump_hexadecimal(int fd, unsigned long value, size_t bytes); + +static LONG WINAPI +faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) +{ + const int fd = fatal_error.fd; + DWORD code = GetExceptionCode(); + + PUTS(fd, "Windows exception: code 0x"); + _Py_dump_hexadecimal(fd, code, sizeof(DWORD)); + PUTS(fd, "\n\n"); + + faulthandler_dump_traceback(fd, fatal_error.all_threads, + fatal_error.interp); + + /* call the next exception handler */ + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + /* Install the handler for fatal signals, faulthandler_fatal_error(). */ static PyObject* @@ -417,7 +438,12 @@ faulthandler_enable(PyObject *self, PyOb } handler->enabled = 1; } + +#ifdef MS_WINDOWS + AddVectoredExceptionHandler(1, faulthandler_exc_handler); +#endif } + Py_RETURN_NONE; } diff -r cf0cac11813d Python/traceback.c --- a/Python/traceback.c Thu Apr 02 09:50:06 2015 +0300 +++ b/Python/traceback.c Thu Apr 02 10:14:13 2015 +0200 @@ -520,10 +520,11 @@ dump_decimal(int fd, int value) This function is signal safe. */ -static void -dump_hexadecimal(int fd, unsigned long value, int width) +void +_Py_dump_hexadecimal(int fd, unsigned long value, size_t bytes) { - int len; + size_t width = bytes * 2; + size_t len; char buffer[sizeof(unsigned long) * 2 + 1]; len = 0; do { @@ -589,15 +590,15 @@ dump_ascii(int fd, PyObject *text) } else if (ch <= 0xff) { PUTS(fd, "\\x"); - dump_hexadecimal(fd, ch, 2); + _Py_dump_hexadecimal(fd, ch, 1); } else if (ch <= 0xffff) { PUTS(fd, "\\u"); - dump_hexadecimal(fd, ch, 4); + _Py_dump_hexadecimal(fd, ch, 2); } else { PUTS(fd, "\\U"); - dump_hexadecimal(fd, ch, 8); + _Py_dump_hexadecimal(fd, ch, 4); } } if (truncated) @@ -692,7 +693,8 @@ write_thread_id(int fd, PyThreadState *t PUTS(fd, "Current thread 0x"); else PUTS(fd, "Thread 0x"); - dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(unsigned long)*2); + _Py_dump_hexadecimal(fd, (unsigned long)tstate->thread_id, + sizeof(unsigned long)); PUTS(fd, " (most recent call first):\n"); }