From: pankrat Date: Wed, 10 Sep 2008 16:24:15 +0000 (+0000) Subject: Issue 2149: Avoid reference cycles caused by frame objects X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8d2d86175baed99dfb68f985e6dbb866876bbf13;p=scons.git Issue 2149: Avoid reference cycles caused by frame objects git-svn-id: http://scons.tigris.org/svn/scons/trunk@3383 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 067f22d0..b790a49f 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -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): diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index b9643071..9b3879eb 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -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]) diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 7e38ffde..5cfde649 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -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()