Graham Dumpleton
grahamd at dscpl.com.au
Tue Jan 3 18:24:16 EST 2006
Graham Dumpleton wrote .. > Martin Blais wrote .. > > After much hacking (all day today), I added the explicit > > Py_EndInterpreter calls and it still hangs on destruction. > > Specifically, it hangs on PyImport_Cleanup() in Py_EndInterpreter(). > > I'm having trouble pinpointing exactly which symbol makes it hang. It > > seems to happen when cleaning the logging module. I saw that logging > > register an atexit hook, tried to remove that, does not fix the > > problem. > > Hmmm, you have gotten ahead of me. I was going to work out some code to > end each interpreter explicitly this morning. FWIW, I would have stuck the following just prior to get_interpreter() call in python_finalize() to try and debug which intepreter it may have been getting stuck in. It is a bit tricky as it makes use of the thread state object that make_interpreter() left inaccessible from when the interepreter was first created. In general, this code probably will not work for more complicated systems where additional C code had created additional thread states associated with an intepreter as the Py_EndInterpreter() call expects there to be only one remaining. Note this assumes that multiple interpreter fix I reference is applied. /* XXX */ PyThreadState *tstate; PyObject *key, *value; char *name; int pos = 0; #ifdef WITH_THREAD PyEval_AcquireLock(); while (PyDict_Next(interpreters, &pos, &key, &value)) { name = PyString_AsString(key); ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, 0, "%d interpreter %s", getpid(), name); if (strcmp(name,MAIN_INTERPRETER) != 0) { idata = (interpreterdata *)PyCObject_AsVoidPtr(value); tstate = idata->istate->tstate_head; PyThreadState_Swap(tstate); ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, 0, "%d end interpreter %s", getpid(), name); Py_EndInterpreter(tstate); PyThreadState_Swap(NULL); ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, 0, "%d done interpreter %s", getpid(), name); } else { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, 0, "%d skip interpreter %s", getpid(), name); } } PyEval_ReleaseLock(); ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, 0, "%d now do finalize", getpid()); #endif /* XXX */
|