Bug in 2.2.2 ???

Greg Chapman glc at well.com
Sat Feb 8 19:58:47 CET 2003


On 7 Feb 2003 05:53:36 -0800, mark.vantassel at visionarysystemsinc.com (Mark
VanTassel) wrote:

>   Py_Initialize();
>   {
>      char * crash_it = 
>         "class anyclass:\n"
>         "   def anyfunc(self,info):\n"
>         "      pass\n";
>
>      char * dont_crash_it =  
>         "class anyclass:\n"
>         "      pass\n";
>
>      PyObject * dict = PyDict_New();
>      PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins() );
>      PyObject * rslt = PyRun_String( crash_it, Py_file_input, dict, dict );
>      Py_DECREF(rslt);
>      Py_DECREF(dict);
>   }
>   Py_Finalize();
>
>   Py_Initialize(); // this fails
>

The difference between the two strings above is that crash_it creates a
reference cycle.  (dict->anyclass->anyfunc->func_globals->dict).  Python does
not run a garbage collection when Py_Finalize is called, so apparently this
cycle survives.  The actual crash occurs during a garbage collection during the
processing of 'import site' (the last thing Py_Initialize does).  I believe this
collection ends up trying to release dict; at any rate, the crash happens when
the collector tries to call Py_ForgetReference on anyclass (specifically,
Py_FatalError("UNREF invalid object") is called).

For 2.2, you can call something like this before calling Py_Finalize:

int garbageCollect(void)
{
    PyObject *ret;
    PyObject *mod = PyImport_ImportModule("gc");
    if (mod == NULL)
        return -1;
    ret = PyObject_CallMethod(mod, "collect", NULL);
    Py_XDECREF(ret);
    Py_DECREF(mod);
    return (ret != NULL) ? 0 : -1;
}

The crash does not occur with 2.3a1.  Some changes have been made to the garbage
collector, but I don't know whether that fixed this problem or it is simply
luck.

---
Greg Chapman





More information about the Python-list mailing list