# HG changeset patch # User Thomas Perl # Date 1496516882 -7200 # Sat Jun 03 21:08:02 2017 +0200 # Node ID 160e27767a070655d4e97b73a59a33c1fc24e3d7 # Parent 4243df51fe43e47419713d3d490ace342097514a Py_SetFatalErrorAbortFunc: Allow embedding program to handle fatal errors This allows graphical programs that dynamically load libpython to handle fatal Python errors gracefully by showing a message dialog before exiting. diff -r 4243df51fe43 -r 160e27767a07 Doc/c-api/sys.rst --- a/Doc/c-api/sys.rst Fri Feb 10 14:19:36 2017 +0100 +++ b/Doc/c-api/sys.rst Sat Jun 03 21:08:02 2017 +0200 @@ -217,7 +217,19 @@ make it dangerous to continue using the Python interpreter; e.g., when the object administration appears to be corrupted. On Unix, the standard C library function :c:func:`abort` is called which will attempt to produce a :file:`core` - file. + file. If an abort function is set with :c:func:`Py_SetFatalErrorAbortFunc`, + it is called with *message* as argument and :c:func:`abort` is not called. + + +.. c:function:: void Py_SetFatalErrorAbortFunc(PyFatalErrorAbortFunc func) + + Set a program-defined function to be called instead of :c:func:`abort` when + :c:func:`Py_FatalError` is called. The embedding program should only use this + as a way of showing a (possibly graphical) error message to the user; the + Python interpreter should not be used, so the process should ideally abort + after notifying the user of the fatal error. + + .. versionadded:: 3.x .. c:function:: void Py_Exit(int status) diff -r 4243df51fe43 -r 160e27767a07 Include/pyerrors.h --- a/Include/pyerrors.h Fri Feb 10 14:19:36 2017 +0100 +++ b/Include/pyerrors.h Sat Jun 03 21:08:02 2017 +0200 @@ -103,6 +103,8 @@ /* Defined in Python/pylifecycle.c */ PyAPI_FUNC(void) Py_FatalError(const char *message) _Py_NO_RETURN; +typedef void (*PyFatalErrorAbortFunc)(const char *message); +PyAPI_FUNC(void) Py_SetFatalErrorAbortFunc(PyFatalErrorAbortFunc func); #if defined(Py_DEBUG) || defined(Py_LIMITED_API) #define _PyErr_OCCURRED() PyErr_Occurred() diff -r 4243df51fe43 -r 160e27767a07 Python/pylifecycle.c --- a/Python/pylifecycle.c Fri Feb 10 14:19:36 2017 +0100 +++ b/Python/pylifecycle.c Sat Jun 03 21:08:02 2017 +0200 @@ -1399,6 +1399,15 @@ /* Print fatal error message and abort */ +static PyFatalErrorAbortFunc * +_fatal_error_abort_func = NULL; + +void +Py_SetFatalErrorAbortFunc(PyFatalErrorAbortFunc func) +{ + _fatal_error_abort_func = func; +} + void Py_FatalError(const char *msg) { @@ -1455,6 +1464,12 @@ DebugBreak(); #endif abort(); + + if (_fatal_error_abort_func != NULL) { + _fatal_error_abort_func(msg); + } else { + abort(); + } } /* Clean up and exit */