[Patches] [ python-Patches-1195571 ] simple callback system for Py_FatalError

SourceForge.net noreply at sourceforge.net
Thu May 5 09:56:46 CEST 2005

Patches item #1195571, was opened at 2005-05-04 15:57
Message generated for change (Comment added) made by jwpye
You can respond by visiting: 

Category: Core (C code)
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: m utku (mutkuk)
Assigned to: Nobody/Anonymous (nobody)
Summary: simple callback system for Py_FatalError 

Initial Comment:
Included implementation of a simple callback system for

Everything is done in "pythonrun.c" and "pydebug.h"


Comment By: James William Pye (jwpye)
Date: 2005-05-05 00:56

Logged In: YES 

Extension case:
Really, if an extension requires special cleanup, chances
are the application will take notice of it and probably
handle that cleanup itself. If extension developers thought
that it was okay to overload the hook, then they might make
the mistake of overloading the hook in an embedded
application where fatal cleanup was a necessity. If a stack
of hooks were provided, who or what determines which hook
should cause the exit? I don't actually have control over
what PostgreSQL does with its FATAL ereport, so if it hit my
hook first, the application will go bye bye, without
touching the others. Also, it might be possible for
extensions to tap into some signal to allow cleanup. For
instance abort(3) sends the process a SIGABRT. All in all, I
still think it's bad mojo.

1: I see your reasoning, but I disagree as when the
developer pokes around the headers it will be more useful
for it, the typedef, to be around the *only* call that the
typedef is used for. Thus showing the complete expectation
for the function's argument, without having to find it in
another file. Matter of fact, I think the typedef isn't
really all that useful except to declare the static function
pointer in pythonrun.c, so I'd rather do without it... =
2. Oh, yeah the NULL check is there just in case someone
gets smart and tries to start running Python calls before
Python is initialized(ala Py_InitializeEx()). Besides that
it, Py_FatalError should only be called once during the
process lifetime, so the extra condition isn't really much
of a performance issue.

I'll e-mail you the patch.


Comment By: m utku (mutkuk)
Date: 2005-05-05 00:21

Logged In: YES 

Extension case:
Extension developers may mess up too, why leave them orphaned?

Doc case:

Your patch is just slicker, why dont I delete this patch and
you submit. What do you say?

I have just 2 suggestions:
1. Declaration of register func would better be in pydebug.h
near Py_FatalError.

2. Last one to call register func owns the hook, this is
just expected case so IMHO remove NULL check from register func.


Comment By: James William Pye (jwpye)
Date: 2005-05-04 23:47

Logged In: YES 

Again, I think this should be explicitly exclusive to an
embedding application, as I cannot imagine a situation where
an extension module should even have access to this facility.

I have done rather limited tests. My application doesn't
seem to like Python 2.5alpha, so I'm going to test the patch
against 2.4.

Sorry to butt into your patch, mutkuk, but here's my
recommendation with docs(ugh, cant attach files):

Index: Doc/api/init.tex
RCS file: /cvsroot/python/python/dist/src/Doc/api/init.tex,v
retrieving revision 1.23
diff -r1.23 init.tex
\begin{cfuncdesc}{void}{Py_InitializeFatalHook}{PyFatalHook fp}
>   Force \cfunction{Py_FatalError()} to invoke the given
>   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.  Giving
>   the application the ability to log the error to a special
>   destination, and to do any appropriate cleanups before
>   If used, this \emph{must} be called prior to
>   \cfunction{Py_Initialize()}.  Otherwise,
>   will set the hook to the default, and future attempts to
>   \cfunction{Py_InitializeFatalHook()} will be ignored.
> \end{cfuncdesc}
Index: Include/pythonrun.h
RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v
retrieving revision 2.65
diff -r2.65 pythonrun.h
> typedef void (*PyFatalHook)(const char *);
> PyAPI_FUNC(void) Py_InitializeFatalHook(PyFatalHook);
Index: Python/pythonrun.c
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.213
diff -r2.213 pythonrun.c
> static PyFatalHook _fatalhook = NULL;
> void
> Py_InitializeFatalHook(PyFatalHook f)
> {
> 	/* Only set it if it is uninitialized. */
> 	if (_fatalhook == NULL)
> 		_fatalhook = f;
> }
> 	Py_InitializeFatalHook(Py_FatalError);
> 	if (_fatalhook != Py_FatalError && _fatalhook != NULL)
> 		_fatalhook(msg);
> 	/* If the hook fell through, finish the process anyways. */


You can respond by visiting: 

More information about the Patches mailing list