Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (revision 85150) +++ Python/pythonrun.c (working copy) @@ -2342,9 +2342,14 @@ /* Print fatal error message and abort */ +static PyFatalHook fatalhook_func = NULL; + void Py_FatalError(const char *msg) { + if (fatalhook_func != NULL && fatalhook_func != Py_FatalError) + fatalhook_func(msg); + fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { @@ -2373,6 +2378,14 @@ abort(); } +PyFatalHook +Py_SetFatalHook(PyFatalHook func) +{ + PyFatalHook old_func = fatalhook_func; + fatalhook_func = func; + return old_func; +} + /* Clean up and exit */ #ifdef WITH_THREAD Index: Include/pythonrun.h =================================================================== --- Include/pythonrun.h (revision 85150) +++ Include/pythonrun.h (working copy) @@ -73,6 +73,9 @@ PyAPI_FUNC(void) PyErr_PrintEx(int); PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); +typedef void (*PyFatalHook)(const char *); +PyAPI_FUNC(PyFatalHook) Py_SetFatalHook(PyFatalHook func); + /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level * exit functions. */ Index: Doc/c-api/sys.rst =================================================================== --- Doc/c-api/sys.rst (revision 85150) +++ Doc/c-api/sys.rst (working copy) @@ -146,6 +146,33 @@ file. +.. cfunction:: PyFatalHook Py_SetFatalHook(PyFatalHook func) + + Cause :cfunc:`Py_FatalError` to invoke the given function instead of printing + to standard error and aborting out of the process. + + This is intended for use in embedded applications that want to define their own + route for handling fatal errors. This gives the application the chance to log + the error to a special destination, and to do any appropriate cleanups before + exiting. + + *func* has the same signature as :cfunc:`Py_FatalError` and will be called with + the *message* argument that was passed to :cfunc:`Py_FatalError`. If *func* is + *NULL*, or if the function does not exit the process, the default behavior + applies. Be careful: the global interpreter lock is not necessarily held. + + :cfunc:`Py_SetFatalHook` returns the previous value of the function. + + +.. ctype:: PyFatalHook + + The type of the hook function called by :cfunc:`Py_FatalError`. Defined as:: + + typedef void (*PyFatalHook)(const char *); + + See :cfunc:`Py_SetFatalHook` for the semantics of PyFatalHook callbacks. + + .. cfunction:: void Py_Exit(int status) .. index::