mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Issue #11393: The fault handler handles also SIGABRT
This commit is contained in:
		
							parent
							
								
									bc6a4db66d
								
							
						
					
					
						commit
						d727e23243
					
				
					 5 changed files with 45 additions and 17 deletions
				
			
		|  | @ -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() | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -112,6 +112,15 @@ def test_sigsegv(self): | |||
|             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): | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -2124,6 +2124,7 @@ Py_FatalError(const char *msg) | |||
|             fflush(stderr); | ||||
|             _Py_DumpTraceback(fd, tstate); | ||||
|         } | ||||
|         _PyFaulthandler_Fini(); | ||||
|     } | ||||
| 
 | ||||
| #ifdef MS_WINDOWS | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner