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

Campbell Barton ideasman42 at gmail.com
Wed Apr 15 06:34:27 CEST 2009


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. @@




More information about the Bf-blender-cvs mailing list