diff options
Diffstat (limited to 'Tools/WAD/Test/wpm.py')
| -rw-r--r-- | Tools/WAD/Test/wpm.py | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/Tools/WAD/Test/wpm.py b/Tools/WAD/Test/wpm.py new file mode 100644 index 0000000..f849e31 --- /dev/null +++ b/Tools/WAD/Test/wpm.py @@ -0,0 +1,280 @@ +# ----------------------------------------------------------------------------- +# WAD Post-mortem debugger +# +# This program can be used to walk up and down the call stack of a mixed +# Python-C program. The following commands are supported: +# +# w - A stack traceback +# u - Go up the call stack +# d - Go down the call stack +# e - Edit a file +# c - Clear the debugger. +# +# David Beazley +# Copyright (C) 2001 +# University of Chicago +# All Rights Reserved +# ----------------------------------------------------------------------------- + +import sys +import os +import traceback +import types +import linecache + + +print "**************************************************" +print "* WAD Debugger *" +print "**************************************************" + +# Save a local copy of the last exception and value objects from sys + +_last_type = sys.last_type +_last_value = sys.last_value +_last_traceback = sys.last_traceback +_last_level = 0 + +_cstack = None # Stack of C-only code +_pystack = None # Stack of Python only code +_combined_stack = None # Combined C-python stack + +_allmode = 0 # Show entire C stack + +# Generalized object for holding stack frames + +class wad_frame: + def __init__(self,frame, n = 0): + if isinstance(frame,types.TupleType): + # A Python traceback object + self.__FILE__ = frame[0] + self.__LINE__ = frame[1] + self.__NAME__ = frame[2] + self.__ARGSTR__ = frame[3] + self.__FRAMENO__ = n + # Make the debugging string + self.__DEBUGSTR__ = "#%-3d [ Python ] in %s in %s, line %d" % (self.__FRAMENO__, self.__ARGSTR__, self.__FILE__, self.__LINE__) + + # Try to get source data + self.__SOURCE__ = "%s, Line %d\n\n" % (self.__FILE__, self.__LINE__) + for i in range(self.__LINE__-2,self.__LINE__+3): + l = linecache.getline(self.__FILE__,i) + if not l: l = '\n' + if (i == self.__LINE__): + self.__SOURCE__ += " => " + else: + self.__SOURCE__ += " " + self.__SOURCE__ += l + self.__frame__ = None + + elif hasattr(frame,"__WAD__"): + # A WAD traceback object + self.__FILE__ = frame.__FILE__ + self.__LINE__ = frame.__LINE__ + self.__NAME__ = frame.__NAME__ + self.__DEBUGSTR__ = frame.__WHERE__ + self.__SOURCE__ = frame.__SOURCE__ + self.__frame__ = frame + + def __str__(self): + return self.__DEBUGSTR__.strip() + + def __getattr__(self,name): + if self.__frame__: + return getattr(self.__frame__,name) + raise AttributeError + + def output(self): + print self + if self.__SOURCE__: + print "\n%s" % (self.__SOURCE__) + + +def wad_build_info(): + global _last_type,_last_value, _last_traceback, _cstack, _combined_stack,_pystack + + _last_type = None + _last_value = None + _last_traceback = None + _cstack = None + _combined_stack = [] + + # Check to see if any exception is defined + if not sys.last_type: + print "No exception has occurred." + return + + # Save a copy of previous exception + _last_type = sys.last_type + _last_value = sys.last_value + _last_traceback = sys.last_traceback + _last_level = 0 + + start_frame = 0 + # Test to see what kind of object it is + if issubclass(_last_type,StandardError): + # Python exception + print "Python exception" + elif hasattr(_last_value[0],"__WAD__"): + # A wad exception frame object + w = sys.last_value[0] + i = 0 + _cstack = [] + while not w[i].__LAST__: + start_frame += 1 + wf = wad_frame(w[i]) + _cstack.append(wf) + i = i + 1 + +# wf = wad_frame(w[i]) +# _cstack.append(wf) +# start_frame += 1 + + # Build the rest of the c stack + _combined_stack = _cstack[:] + while i < len(w): + wf = wad_frame(w[i]) + _cstack.append(wf) + i = i + 1 + + else: + print "Unknown error" + + # Build the Python call stack + _pystack = [] + t = sys.last_traceback + tp = None + while hasattr(t,"tb_frame"): + tp = t + t = t.tb_next + + fr = traceback.extract_stack(tp.tb_frame) + for i in range(len(fr),0,-1): + f = wad_frame(fr[i-1], start_frame) + start_frame += 1 + _pystack.append(f) + _combined_stack.extend(_pystack) + + +wad_build_info() + +class where_impl: + def __init__(self): + self.all = 0; + self.cstack = 0 + + def __repr__(self): + global _combined_stack, _cstack, _last_level + if (self.cstack): + stack = _cstack + else: + stack = _combined_stack + + if not stack: + print "No current exception." + return "" + + last_source = None + for i in range(len(stack),0,-1): + f = stack[i-1] + print f + if (f.__SOURCE__): + last_source = f.__SOURCE__ + _last_level = i-1 + if last_source: print "\n%s" % last_source + return "" + + def __getitem__(self,n): + global _last_level, _cstack, _combined_stack + if (self.cstack): + stack = _cstack + else: + stack = _combined_stack + _last_level = n + stack[_last_level].output() + return None + + def __len__(self): + return len(frame) + + +where = where_impl() +w = where + +class up_impl: + def __repr__(self): + global _last_level, _combined_stack, _cstack + if where.cstack: + stack = _cstack + else: + stack = _combined_stack + + if not stack: + return "" + _last_level += 1 + stack[_last_level].output() + return "" + +up = up_impl() +u = up + +class down_impl: + def __repr__(self): + global _last_level, _combined_stack, _cstack + if where.cstack: + stack = _cstack + else: + stack = _combined_stack + + if not stack: + return "" + _last_level -= 1 + stack[_last_level].output() + return "" + +down = down_impl() +d = down + +class clear_impl: + def __repr__(self): + global _last_exc, _last_level, frame + _last_exc = None + frame = None + +clear = clear_impl() +c = clear + +class edit_impl: + def __repr__(self): + global _last_level, _combined_stack, _cstack + if where.cstack: + stack = _cstack + else: + stack = _combined_stack + + if not stack: + return "" + f = stack[_last_level] + e = os.getenv("EDITOR","vi") + if f.__FILE__: + os.system("%s +%d %s" % (e,f.__LINE__,f.__FILE__)) + return "" + +edit = edit_impl() +e = edit + +class var_impl: + def __getattr__(self,name): + if (w.cstack): + stack = _cstack + else: + stack = _combined_stack + + return getattr(stack[_last_level],name) + + +v = var_impl() + + +repr(w) + + |
