summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-09-18 12:41:15 (GMT)
committerSteven Knight <knight@baldmt.com>2004-09-18 12:41:15 (GMT)
commit80a0699a0a8de7400e34c2e72dce9b9abebd674d (patch)
treea6471aa2c86cfe1d44b297e29d7df306152b477d /src
parentf60958ba86ac7d131bdcbce5a40bd820b23ff9dd (diff)
downloadSCons-80a0699a0a8de7400e34c2e72dce9b9abebd674d.zip
SCons-80a0699a0a8de7400e34c2e72dce9b9abebd674d.tar.gz
SCons-80a0699a0a8de7400e34c2e72dce9b9abebd674d.tar.bz2
Print tracebacks for errors other than UserError and StopError. (Gary Oberbrunner)
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Script/__init__.py19
-rw-r--r--src/engine/SCons/Taskmaster.py9
-rw-r--r--src/engine/SCons/TaskmasterTests.py22
4 files changed, 44 insertions, 9 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index b035acb..1965c61 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -73,6 +73,9 @@ RELEASE 0.97 - XXX
- Add a PRINT_CMD_LINE_FUNC construction variable to allow people
to filter (or log) command-line output.
+ - Print an internal Python stack trace in response to an otherwise
+ unexplained error when --debug=stacktrace is specified.
+
From Kevin Quick:
- Fix the Builder name returned from ListBuilders and other instances
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index dfee767..160fae3 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -141,8 +141,12 @@ class BuildTask(SCons.Taskmaster.Task):
# is to display the various types of Errors and Exceptions
# appropriately.
status = 2
- t, e = self.exc_info()[:2]
- tb = None
+ exc_info = self.exc_info()
+ try:
+ t, e, tb = exc_info
+ except ValueError:
+ t, e = exc_info
+ tb = None
if t is None:
# The Taskmaster didn't record an exception for this Task;
# see if the sys module has one.
@@ -166,7 +170,7 @@ class BuildTask(SCons.Taskmaster.Task):
s = s + ' Stop.'
sys.stderr.write("scons: *** %s\n" % s)
- if tb:
+ if tb and print_stacktrace:
sys.stderr.write("scons: internal stack trace:\n")
traceback.print_tb(tb, file=sys.stderr)
@@ -240,6 +244,7 @@ print_dtree = 0
print_explanations = 0
print_includes = 0
print_objects = 0
+print_stacktrace = 0
print_time = 0
print_tree = 0
memory_stats = None
@@ -400,7 +405,8 @@ def _set_globals(options):
global repositories, keep_going_on_error, ignore_errors
global print_count, print_dtree
global print_explanations, print_includes
- global print_objects, print_time, print_tree
+ global print_objects, print_stacktrace
+ global print_time, print_tree
global memory_outf, memory_stats
if options.repository:
@@ -423,6 +429,8 @@ def _set_globals(options):
print_objects = 1
elif options.debug == "presub":
SCons.Action.print_actions_presub = 1
+ elif options.debug == "stacktrace":
+ print_stacktrace = 1
elif options.debug == "time":
print_time = 1
elif options.debug == "tree":
@@ -520,7 +528,8 @@ class OptParser(OptionParser):
debug_options = ["count", "dtree", "explain",
"includes", "memory", "objects",
- "pdb", "presub", "time", "tree"]
+ "pdb", "presub", "stacktrace",
+ "time", "tree"]
def opt_debug(option, opt, value, parser, debug_options=debug_options):
if value in debug_options:
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index dab5026..84eb08d 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -461,5 +461,10 @@ class Taskmaster:
self.pending = []
def exception_raise(self, exception):
- exc_type, exc_value = exception[:2]
- raise exc_type, exc_value
+ exc = exception[:]
+ try:
+ exc_type, exc_value, exc_traceback = exc
+ except ValueError:
+ exc_type, exc_value = exc
+ exc_traceback = None
+ raise exc_type, exc_value, exc_traceback
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index 8865e09..a908192 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -921,7 +921,25 @@ class TaskmasterTestCase(unittest.TestCase):
else:
assert 0, "did not catch expected exception"
- t.exception_set(("exception 3", "XYZZY"))
+ try:
+ 1/0
+ except:
+ tb = sys.exc_info()[2]
+ t.exception_set(("exception 3", "arg", tb))
+ try:
+ t.exception_raise()
+ except:
+ exc_type, exc_value, exc_tb = sys.exc_info()
+ assert exc_type == 'exception 3', exc_type
+ assert exc_value == "arg", exc_value
+ import traceback
+ x = traceback.extract_tb(tb)[-1]
+ y = traceback.extract_tb(exc_tb)[-1]
+ assert x == y, "x = %s, y = %s" % (x, y)
+ else:
+ assert 0, "did not catch expected exception"
+
+ t.exception_set(("exception 4", "XYZZY"))
def fw_exc(exc):
raise 'exception_forwarded', exc
tm.exception_raise = fw_exc
@@ -930,7 +948,7 @@ class TaskmasterTestCase(unittest.TestCase):
except:
exc_type, exc_value = sys.exc_info()[:2]
assert exc_type == 'exception_forwarded', exc_type
- assert exc_value[0] == "exception 3", exc_value[0]
+ assert exc_value[0] == "exception 4", exc_value[0]
assert exc_value[1] == "XYZZY", exc_value[1]
else:
assert 0, "did not catch expected exception"