Message122846
I discovered this bug working with panda3d. I've attached a short
python script which demonstrates the problem. After installing
panda3d, run the script, and then hit q in the window which appears.
You'll see that none of the cleanup code after the 'run()' main loop
runs.
The underlying cause is in how panda3d uses the C API. It's got code
like this (in src/pipeline/thread.cxx):
// Call the user's function.
result = PyObject_Call(function, args, NULL);
if (result == (PyObject *)NULL && PyErr_Occurred()) {
// We got an exception. Move the exception from the current
// thread into the main thread, so it can be handled there.
PyObject *exc, *val, *tb;
PyErr_Fetch(&exc, &val, &tb);
thread_cat.error()
<< "Exception occurred within " << *this << "\n";
// Temporarily restore the exception state so we can print a
// callback on-the-spot.
Py_XINCREF(exc);
Py_XINCREF(val);
Py_XINCREF(tb);
PyErr_Restore(exc, val, tb);
PyErr_Print();
...
If the code being called (generally a panda3d task function or event
handler) calls sys.exit, the PyErr_Print() never returns. This is
surprising, as the the documentation never mentions that a function
with an innocuous name like "Print" might never return.
However, I don't think this is a panda3d bug; I think that the
function as documented is the way it should behave. Otherwise, the
vast majority of calls to this method will need to look like
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
PyErr_PrintEx(1);
}
which seems like a poor abstraction.
Another unexpected side effect is when python is used with the -i
flag. Because of the way this alters the normal exit behavior, the
code runs the way I'd expect, and the cleanup code in the test
application *does* run. It seems rather strange to me that cleanup
code should run or not run based on the -i flag.
I believe the fix for all this is that PyErr_PrintEx be changed to
behave as documented, *not* call handle_system_exit() when passed
SystemExit, and instead in the places where the interpreter main loop
is run, followed by PyErr_PrintEx(), that SystemExit is special cased
in those specific locations as needed. |
|
Date |
User |
Action |
Args |
2010-11-29 18:46:33 | Marc.Horowitz | set | recipients:
+ Marc.Horowitz |
2010-11-29 18:46:32 | Marc.Horowitz | set | messageid: <1291056392.92.0.0604779345933.issue10582@psf.upfronthosting.co.za> |
2010-11-29 18:46:30 | Marc.Horowitz | link | issue10582 messages |
2010-11-29 18:46:30 | Marc.Horowitz | create | |
|