]> granicus.if.org Git - python/commitdiff
Issue #11393: The fault handler handles also SIGABRT
authorVictor Stinner <victor.stinner@haypocalc.com>
Fri, 1 Apr 2011 10:13:55 +0000 (12:13 +0200)
committerVictor Stinner <victor.stinner@haypocalc.com>
Fri, 1 Apr 2011 10:13:55 +0000 (12:13 +0200)
Doc/library/faulthandler.rst
Doc/using/cmdline.rst
Lib/test/test_faulthandler.py
Modules/faulthandler.c
Python/pythonrun.c

index 7b106bc68b779da3ecf31f6871816fe39e49091a..106da45b4ce2cd85f76dfd017e738fbca9f74ed7 100644 (file)
@@ -6,10 +6,10 @@
 
 This module contains functions to dump the Python traceback explicitly, on a
 fault, after a timeout or on a user signal. Call :func:`faulthandler.enable` to
-install fault handlers for :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGBUS`
-and :const:`SIGILL` signals. You can also enable them at startup by setting the
-:envvar:`PYTHONFAULTHANDLER` environment variable or by using :option:`-X`
-``faulthandler`` command line option.
+install fault handlers for :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`,
+:const:`SIGBUS` and :const:`SIGILL` signals. You can also enable them at
+startup by setting the :envvar:`PYTHONFAULTHANDLER` environment variable or by
+using :option:`-X` ``faulthandler`` command line option.
 
 The fault handler is compatible with system fault handlers like Apport or
 the Windows fault handler. The module uses an alternative stack for signal
@@ -48,9 +48,9 @@ Fault handler state
 .. function:: enable(file=sys.stderr, all_threads=False)
 
    Enable the fault handler: install handlers for :const:`SIGSEGV`,
-   :const:`SIGFPE`, :const:`SIGBUS` and :const:`SIGILL` signals to dump the
-   Python traceback. It dumps the traceback of the current thread, or all
-   threads if *all_threads* is ``True``, into *file*.
+   :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS` and :const:`SIGILL`
+   signals to dump the Python traceback. It dumps the traceback of the current
+   thread, or all threads if *all_threads* is ``True``, into *file*.
 
 .. function:: disable()
 
index 8a5a66278dbbbe058e520d180c546add07d9520b..72b77cd3b95027f68e3cfd03c7a234705538672a 100644 (file)
@@ -502,8 +502,9 @@ These environment variables influence Python's behavior.
 
    If this environment variable is set, :func:`faulthandler.enable` is called
    at startup: install a handler for :const:`SIGSEGV`, :const:`SIGFPE`,
-   :const:`SIGBUS` and :const:`SIGILL` signals to dump the Python traceback.
-   This is equivalent to :option:`-X` ``faulthandler`` option.
+   :const:`SIGABRT`, :const:`SIGBUS` and :const:`SIGILL` signals to dump the
+   Python traceback.  This is equivalent to :option:`-X` ``faulthandler``
+   option.
 
 
 Debug-mode variables
index f26269c7bd47b00918ce9a4f85d3e6fae0d20612..1a79c5065613c14e3cd946dc8f2f675eed7fb158 100644 (file)
@@ -112,6 +112,15 @@ faulthandler._sigsegv()
             3,
             'Segmentation fault')
 
+    def test_sigabrt(self):
+        self.check_fatal_error("""
+import faulthandler
+faulthandler.enable()
+faulthandler._sigabrt()
+""".strip(),
+            3,
+            'Aborted')
+
     @unittest.skipIf(sys.platform == 'win32',
                      "SIGFPE cannot be caught on Windows")
     def test_sigfpe(self):
index 5ec94f0a9fb8a2e5a72f9264062ea12a1bb91578..abff79e434dae9dd4178950a40ea00571a52d26b 100644 (file)
@@ -10,9 +10,9 @@
 #endif
 
 #ifndef MS_WINDOWS
-   /* register() is useless on Windows, because only SIGSEGV and SIGILL can be
-      handled by the process, and these signals can only be used with enable(),
-      not using register() */
+   /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
+      SIGILL can be handled by the process, and these signals can only be used
+      with enable(), not using register() */
 #  define FAULTHANDLER_USER
 #endif
 
@@ -96,6 +96,7 @@ static fault_handler_t faulthandler_handlers[] = {
     {SIGILL, 0, "Illegal instruction", },
 #endif
     {SIGFPE, 0, "Floating point exception", },
+    {SIGABRT, 0, "Aborted", },
     /* define SIGSEGV at the end to make it the default choice if searching the
        handler fails in faulthandler_fatal_error() */
     {SIGSEGV, 0, "Segmentation fault", }
@@ -202,7 +203,7 @@ faulthandler_dump_traceback_py(PyObject *self,
 }
 
 
-/* Handler of SIGSEGV, SIGFPE, SIGBUS and SIGILL signals.
+/* Handler of SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
 
    Display the current Python traceback, restore the previous handler and call
    the previous handler.
@@ -253,9 +254,9 @@ faulthandler_fatal_error(
     PUTS(fd, handler->name);
     PUTS(fd, "\n\n");
 
-    /* SIGSEGV, SIGFPE, SIGBUS and SIGILL are synchronous signals and so are
-       delivered to the thread that caused the fault. Get the Python thread
-       state of the current thread.
+    /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
+       so are delivered to the thread that caused the fault. Get the Python
+       thread state of the current thread.
 
        PyThreadState_Get() doesn't give the state of the thread that caused the
        fault if the thread released the GIL, and so this function cannot be
@@ -282,7 +283,7 @@ faulthandler_fatal_error(
     raise(signum);
 }
 
-/* Install handler for fatal signals (SIGSEGV, SIGFPE, ...). */
+/* Install the handler for fatal signals, faulthandler_fatal_error(). */
 
 static PyObject*
 faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
@@ -714,6 +715,20 @@ faulthandler_sigfpe(PyObject *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+static PyObject *
+faulthandler_sigabrt(PyObject *self, PyObject *args)
+{
+#if _MSC_VER
+    /* If Python is compiled in debug mode with Visual Studio, abort() opens
+       a popup asking the user how to handle the assertion. Use raise(SIGABRT)
+       instead. */
+    raise(SIGABRT);
+#else
+    abort();
+#endif
+    Py_RETURN_NONE;
+}
+
 #ifdef SIGBUS
 static PyObject *
 faulthandler_sigbus(PyObject *self, PyObject *args)
@@ -847,6 +862,8 @@ static PyMethodDef module_methods[] = {
                "a SIGSEGV or SIGBUS signal depending on the platform")},
     {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
      PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
+    {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
+     PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
     {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
      PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
 #ifdef SIGBUS
index f787a4f8b372b27d66a2afdb319ee6ce85680e2e..1c36e63ac46e569cc0b459e42c73cbb9b50c1d00 100644 (file)
@@ -2124,6 +2124,7 @@ Py_FatalError(const char *msg)
             fflush(stderr);
             _Py_DumpTraceback(fd, tstate);
         }
+        _PyFaulthandler_Fini();
     }
 
 #ifdef MS_WINDOWS