Issue 2149: Avoid reference cycles caused by frame objects
authorpankrat <pankrat@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 10 Sep 2008 16:24:15 +0000 (16:24 +0000)
committerpankrat <pankrat@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 10 Sep 2008 16:24:15 +0000 (16:24 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@3383 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Defaults.py
src/engine/SCons/SConf.py
src/engine/SCons/Script/SConscript.py

index 067f22d012693f80a9c13516841620f7916ad350..b790a49f7515d9d6a243fb014970ac2f524bef78 100644 (file)
@@ -424,7 +424,10 @@ class Variable_Method_Caller:
         self.method = method
     def __call__(self, *args, **kw):
         try: 1/0
-        except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
+        except ZeroDivisionError: 
+            # Don't start iterating with the current stack-frame to
+            # prevent creating reference cycles (f_back is safe).
+            frame = sys.exc_info()[2].tb_frame.f_back
         variable = self.variable
         while frame:
             if frame.f_locals.has_key(variable):
index b964307143b2f534c2f960e882a21c779dc6f6a8..9b3879eb2b267d2e36cb4f87a7f99f9e4abd416c 100644 (file)
@@ -235,7 +235,9 @@ class SConfBuildTask(SCons.Taskmaster.Task):
             raise
         elif issubclass(exc_type, SCons.Errors.BuildError):
             # we ignore Build Errors (occurs, when a test doesn't pass)
-            pass
+            # Clear the exception to prevent the contained traceback
+            # to build a reference cycle.
+            self.exc_clear()
         else:
             self.display('Caught exception while building "%s":\n' %
                          self.targets[0])
index 7e38ffdefab030d2c1d17606975d25ada1bdb813..5cfde6499e5fa1770bec758cb806674f748d40a4 100644 (file)
@@ -81,7 +81,10 @@ def get_calling_namespaces():
     """Return the locals and globals for the function that called
     into this module in the current call stack."""
     try: 1/0
-    except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
+    except ZeroDivisionError: 
+        # Don't start iterating with the current stack-frame to
+        # prevent creating reference cycles (f_back is safe).
+        frame = sys.exc_info()[2].tb_frame.f_back
 
     # Find the first frame that *isn't* from this file.  This means
     # that we expect all of the SCons frames that implement an Export()