summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLudwig Hähne <pankrat@tigris.org>2008-09-10 16:24:15 (GMT)
committerLudwig Hähne <pankrat@tigris.org>2008-09-10 16:24:15 (GMT)
commit1c280140f557190a9625397bbe9e5a3a540efac5 (patch)
tree481d1b99880d2a2d4bf3470fca80032eaa237597
parent311e482d13e4bfbcd643e0fb7cdc017ac55b6dc9 (diff)
downloadSCons-1c280140f557190a9625397bbe9e5a3a540efac5.zip
SCons-1c280140f557190a9625397bbe9e5a3a540efac5.tar.gz
SCons-1c280140f557190a9625397bbe9e5a3a540efac5.tar.bz2
Issue 2149: Avoid reference cycles caused by frame objects
-rw-r--r--src/engine/SCons/Defaults.py5
-rw-r--r--src/engine/SCons/SConf.py4
-rw-r--r--src/engine/SCons/Script/SConscript.py5
3 files changed, 11 insertions, 3 deletions
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index 067f22d..b790a49 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 b964307..9b3879e 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 7e38ffd..5cfde64 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()