[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19724] trunk/blender/source: Fix for own recent reference count error.

joe joeedh at gmail.com
Wed Apr 15 07:35:38 CEST 2009


What is the armature weaklist, btw?  I never could figure that out.

Joe

On Tue, Apr 14, 2009 at 10:34 PM, Campbell Barton <ideasman42 at gmail.com> wrote:
> Revision: 19724
>          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19724
> Author:   campbellbarton
> Date:     2009-04-15 06:34:27 +0200 (Wed, 15 Apr 2009)
>
> Log Message:
> -----------
> Fix for own recent reference count error.
> - The armature weakref list was  being incref'd twice then decrefed twice (incref and decref were used incorrectly), now only once. My 'fix' broke this.
> - In bpy_pydriver_create_dict the 2 refs added from running PyDict_SetItemString twice were undone when clearing the dictionary (added comment)
> - changed Py_XDECREF to Py_DECREF int BPY_pyconstraint_update and BPY_pyconstraint_target, Py_XDECREF checs for NULL value which would have crashed blender before it got to Py_XDECREF anyway.
> - after every error is reported (PyErr_Print), remove sys.last_traceback and clear the error, I found this fixed certain crashes (usually when starting the game engine or exiting blender), so best do this all the time.
>
> - header_text.c, CcdPhysicsEnvironment.cpp, KX_CameraActuator.cpp - remove some warnings.
>
> Modified Paths:
> --------------
>    trunk/blender/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
>    trunk/blender/source/blender/python/BPY_interface.c
>    trunk/blender/source/blender/python/api2_2x/Draw.c
>    trunk/blender/source/blender/python/api2_2x/bpy_internal_import.c
>    trunk/blender/source/blender/src/header_text.c
>    trunk/blender/source/blender/src/imagepaint.c
>    trunk/blender/source/gameengine/GameLogic/SCA_PythonController.cpp
>    trunk/blender/source/gameengine/Ketsji/KX_CameraActuator.cpp
>    trunk/blender/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
>    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
>
> Modified: trunk/blender/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
> ===================================================================
> --- trunk/blender/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c   2009-04-15 03:22:22 UTC (rev 19723)
> +++ trunk/blender/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c   2009-04-15 04:34:27 UTC (rev 19724)
> @@ -340,7 +340,11 @@
>        PyGILState_STATE gilstate = PyGILState_Ensure();
>
>        fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name);
> -       if (PyErr_Occurred()) { PyErr_Print(); }
> +       if (PyErr_Occurred()) {
> +               PyErr_Print();
> +               PyErr_Clear();
> +               PySys_SetObject("last_traceback", NULL);
> +       }
>        else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); }
>
>        PyGILState_Release(gilstate);
>
> Modified: trunk/blender/source/blender/python/BPY_interface.c
> ===================================================================
> --- trunk/blender/source/blender/python/BPY_interface.c 2009-04-15 03:22:22 UTC (rev 19723)
> +++ trunk/blender/source/blender/python/BPY_interface.c 2009-04-15 04:34:27 UTC (rev 19724)
> @@ -97,6 +97,17 @@
>  PyObject *bpy_orig_syspath_List = NULL;
>
>
> +static void BPY_Err_Clear(void)
> +{
> +       /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
> +        * their user count. Not to mention holding references to wrapped data.
> +        * This is especially bad when the PyObject for the wrapped data is free'd, after blender
> +        * has alredy dealocated the pointer */
> +       PySys_SetObject( "last_traceback", NULL);
> +
> +       PyErr_Clear();
> +}
> +
>  /*
>  * set up a weakref list for Armatures
>  *    creates list in __main__ module dict
> @@ -107,30 +118,29 @@
>        PyObject *maindict;
>        PyObject *main_module;
>        PyObject *list;
> -       char *list_name = ARM_WEAKREF_LIST_NAME;
> +       PyObject *list_name = PyString_FromString(ARM_WEAKREF_LIST_NAME);
>
>        main_module = PyImport_AddModule( "__main__");
>        if(main_module){
> -               PyObject *weakreflink;
>                maindict= PyModule_GetDict(main_module);
>
>                /* check if there is already a dict entry for the armature weakrefs,
>                 * and delete if so before making another one */
> -
> -               weakreflink= PyDict_GetItemString(maindict,list_name);
> -               if( weakreflink != NULL ) {
> -                       PyDict_DelItemString(maindict,list_name);
> -                       Py_XDECREF( weakreflink );
> -               }
>
> +               if (PyDict_DelItem(maindict, list_name)==-1)
> +                       PyErr_Clear();
> +
>                list= PyList_New(0);
> -               if (PyDict_SetItemString(maindict, list_name, list) == -1){
> -                       printf("Oops - setup_armature_weakrefs()\n");
> +               if (PyDict_SetItem(maindict, list_name, list) == -1){
> +                       PyErr_Print();
> +                       BPY_Err_Clear();
>                        Py_DECREF(list);
> +                       Py_DECREF(list_name);
>                        return 0;
>                }
>                Py_DECREF(list); /* the dict owns it now */
>        }
> +       Py_DECREF(list_name);
>        return 1;
>  }
>
> @@ -532,16 +542,6 @@
>        else return PyString_FromString("unknown");
>  }
>
> -static void BPY_Err_Clear(void)
> -{
> -       /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
> -        * their user count. Not to mention holding references to wrapped data.
> -        * This is especially bad when the PyObject for the wrapped data is free'd, after blender
> -        * has alredy dealocated the pointer */
> -       PySys_SetObject( "last_traceback", Py_None);
> -
> -       PyErr_Clear();
> -}
>  /****************************************************************************
>  * Description: Blender Python error handler. This catches the error and
>  * stores filename and line number in a global
> @@ -1137,6 +1137,7 @@
>
>        if( PyErr_Occurred(  ) ) {      /* if script ended after filesel */
>                PyErr_Print(  );        /* eventual errors are handled now */
> +               BPY_Err_Clear(  );
>                error_pyscript(  );
>        }
>
> @@ -1245,10 +1246,9 @@
>        if (mod) {
>                PyDict_SetItemString(d, "Blender", mod);
>                PyDict_SetItemString(d, "b", mod);
> -               Py_DECREF(mod);
> -               Py_DECREF(mod);
> +               Py_DECREF(mod); /* 2 refs above are cleared with the dict, only decref the ref from PyImport_ImportModule */
>        } else {
> -               PyErr_Clear();
> +               BPY_Err_Clear();
>        }
>
>        mod = PyImport_ImportModule("math");
> @@ -1258,18 +1258,18 @@
>                /* Only keep for backwards compat! - just import all math into root, they are standard */
>                PyDict_SetItemString(d, "math", mod);
>                PyDict_SetItemString(d, "m", mod);
> -               Py_DECREF(mod);
> -               Py_DECREF(mod);
> -       }
> +               Py_DECREF(mod); /* 2 refs above are cleared with the dict, only decref the ref from PyImport_ImportModule */
> +       } else {
> +               BPY_Err_Clear();
> +       }
>
>        mod = PyImport_ImportModule("Blender.Noise");
>        if (mod) {
>                PyDict_SetItemString(d, "noise", mod);
>                PyDict_SetItemString(d, "n", mod);
> -               Py_DECREF(mod);
> -               Py_DECREF(mod);
> +               Py_DECREF(mod); /* 2 refs above are cleared with the dict, only decref the ref from PyImport_ImportModule */
>        } else {
> -               PyErr_Clear();
> +               BPY_Err_Clear();
>        }
>
>        /* If there's a Blender text called pydrivers.py, import it.
> @@ -1279,10 +1279,9 @@
>                if (mod) {
>                        PyDict_SetItemString(d, "pydrivers", mod);
>                        PyDict_SetItemString(d, "p", mod);
> -                       Py_DECREF(mod);
> -                       Py_DECREF(mod);
> +                       Py_DECREF(mod); /* 2 refs above are cleared with the dict, only decref the ref from PyImport_ImportModule */
>                } else {
> -                       PyErr_Clear();
> +                       BPY_Err_Clear();
>                }
>        }
>        /* short aliases for some Get() functions: */
> @@ -1297,7 +1296,7 @@
>                        Py_DECREF(fcn);
>                }
>        } else {
> -               PyErr_Clear();
> +               BPY_Err_Clear();
>        }
>
>        /* TODO - change these */
> @@ -1311,7 +1310,7 @@
>                        Py_DECREF(fcn);
>                }
>        } else {
> -               PyErr_Clear();
> +               BPY_Err_Clear();
>        }
>
>        /* ma(matname) == Blender.Material.Get(matname) */
> @@ -1324,7 +1323,7 @@
>                        Py_DECREF(fcn);
>                }
>        } else {
> -               PyErr_Clear();
> +               BPY_Err_Clear();
>        }
>
>        return 0;
> @@ -1350,6 +1349,7 @@
>                fprintf(stderr, "\nError in Ipo Driver: No Object\nThis is the failed Python expression:\n'%s'\n\n", driver->name);
>
>        PyErr_Print();
> +       BPY_Err_Clear();
>
>        return 0.0f;
>  }
> @@ -1445,7 +1445,7 @@
>                        return;
>                }
>
> -               Py_XDECREF(retval);
> +               Py_DECREF(retval);
>                retval = NULL;
>
>                /* try to find NUM_TARGETS */
> @@ -1578,9 +1578,9 @@
>                con->flag |= PYCON_SCRIPTERROR;
>
>                /* free temp objects */
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(srcmat);
> -               Py_XDECREF(tarmats);
> +               Py_DECREF(idprop);
> +               Py_DECREF(srcmat);
> +               Py_DECREF(tarmats);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1589,7 +1589,7 @@
>                return;
>        }
>
> -       if (retval) {Py_XDECREF( retval );}
> +       Py_DECREF( retval );
>        retval = NULL;
>
>        gval = PyDict_GetItemString(globals, "doConstraint");
> @@ -1597,9 +1597,9 @@
>                printf("ERROR: no doConstraint function in constraint!\n");
>
>                /* free temp objects */
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(srcmat);
> -               Py_XDECREF(tarmats);
> +               Py_DECREF(idprop);
> +               Py_DECREF(srcmat);
> +               Py_DECREF(tarmats);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1612,15 +1612,15 @@
>        if (PyFunction_Check(gval)) {
>                pyargs = Py_BuildValue("OOO", srcmat, tarmats, idprop);
>                retval = PyObject_CallObject(gval, pyargs);
> -               Py_XDECREF(pyargs);
> +               Py_DECREF(pyargs);
>        }
>        else {
>                printf("ERROR: doConstraint is supposed to be a function!\n");
>                con->flag |= PYCON_SCRIPTERROR;
>
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(srcmat);
> -               Py_XDECREF(tarmats);
> +               Py_DECREF(idprop);
> +               Py_DECREF(srcmat);
> +               Py_DECREF(tarmats);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1634,9 +1634,9 @@
>                con->flag |= PYCON_SCRIPTERROR;
>
>                /* free temp objects */
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(srcmat);
> -               Py_XDECREF(tarmats);
> +               Py_DECREF(idprop);
> +               Py_DECREF(srcmat);
> +               Py_DECREF(tarmats);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1650,10 +1650,10 @@
>                printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
>                con->flag |= PYCON_SCRIPTERROR;
>
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(srcmat);
> -               Py_XDECREF(tarmats);
> -               Py_XDECREF(retval);
> +               Py_DECREF(idprop);
> +               Py_DECREF(srcmat);
> +               Py_DECREF(tarmats);
> +               Py_DECREF(retval);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1667,10 +1667,10 @@
>                printf("Error in PyConstraint - doConstraint: Matrix returned is the wrong size!\n");
>                con->flag |= PYCON_SCRIPTERROR;
>
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(srcmat);
> -               Py_XDECREF(tarmats);
> -               Py_XDECREF(retval);
> +               Py_DECREF(idprop);
> +               Py_DECREF(srcmat);
> +               Py_DECREF(tarmats);
> +               Py_DECREF(retval);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1687,10 +1687,10 @@
>        }
>
>        /* free temp objects */
> -       Py_XDECREF(idprop);
> -       Py_XDECREF(srcmat);
> -       Py_XDECREF(tarmats);
> -       Py_XDECREF(retval);
> +       Py_DECREF(idprop);
> +       Py_DECREF(srcmat);
> +       Py_DECREF(tarmats);
> +       Py_DECREF(retval);
>
>        /* clear globals */
>        ReleaseGlobalDictionary(globals);
> @@ -1745,10 +1745,10 @@
>                con->flag |= PYCON_SCRIPTERROR;
>
>                /* free temp objects */
> -               Py_XDECREF(tar);
> -               Py_XDECREF(subtar);
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(tarmat);
> +               Py_DECREF(tar);
> +               Py_DECREF(subtar);
> +               Py_DECREF(idprop);
> +               Py_DECREF(tarmat);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1757,17 +1757,17 @@
>                return;
>        }
>
> -       Py_XDECREF(retval);
> +       Py_DECREF(retval);
>        retval = NULL;
>
>        /* try to find doTarget function to set the target matrix */
>        gval = PyDict_GetItemString(globals, "doTarget");
>        if (!gval) {
>                /* free temp objects */
> -               Py_XDECREF(tar);
> -               Py_XDECREF(subtar);
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(tarmat);
> +               Py_DECREF(tar);
> +               Py_DECREF(subtar);
> +               Py_DECREF(idprop);
> +               Py_DECREF(tarmat);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1780,16 +1780,16 @@
>        if (PyFunction_Check(gval)) {
>                pyargs = Py_BuildValue("OOOO", tar, subtar, tarmat, idprop);
>                retval = PyObject_CallObject(gval, pyargs);
> -               Py_XDECREF(pyargs);
> +               Py_DECREF(pyargs);
>        }
>        else {
>                printf("ERROR: doTarget is supposed to be a function!\n");
>                con->flag |= PYCON_SCRIPTERROR;
>
> -               Py_XDECREF(tar);
> -               Py_XDECREF(subtar);
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(tarmat);
> +               Py_DECREF(tar);
> +               Py_DECREF(subtar);
> +               Py_DECREF(idprop);
> +               Py_DECREF(tarmat);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1804,10 +1804,10 @@
>
>
>                /* free temp objects */
> -               Py_XDECREF(tar);
> -               Py_XDECREF(subtar);
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(tarmat);
> +               Py_DECREF(tar);
> +               Py_DECREF(subtar);
> +               Py_DECREF(idprop);
> +               Py_DECREF(tarmat);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1819,11 +1819,11 @@
>        if (!PyObject_TypeCheck(retval, &matrix_Type)) {
>                con->flag |= PYCON_SCRIPTERROR;
>
> -               Py_XDECREF(tar);
> -               Py_XDECREF(subtar);
> -               Py_XDECREF(idprop);
> -               Py_XDECREF(tarmat);
> -               Py_XDECREF(retval);
> +               Py_DECREF(tar);
> +               Py_DECREF(subtar);
> +               Py_DECREF(idprop);
> +               Py_DECREF(tarmat);
> +               Py_DECREF(retval);
>
>                ReleaseGlobalDictionary(globals);
>
> @@ -1837,11 +1837,11 @@
>                printf("Error in PyConstraint - doTarget: Matrix returned is the wrong size!\n");
>                con->flag |= PYCON_SCRIPTERROR;
>
> -               Py_XDECREF(tar);
> -               Py_XDECREF(subtar);
>
> @@ Diff output truncated at 10240 characters. @@
>
> _______________________________________________
> Bf-blender-cvs mailing list
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>


More information about the Bf-committers mailing list