|
@@ -1,8 +1,11 @@
|
|
|
|
|
+from pandac.PandaModules import ConfigConfigureGetConfigConfigShowbase as config
|
|
|
from direct.directnotify.DirectNotifyGlobal import directNotify
|
|
from direct.directnotify.DirectNotifyGlobal import directNotify
|
|
|
from direct.showbase.PythonUtil import fastRepr
|
|
from direct.showbase.PythonUtil import fastRepr
|
|
|
from exceptions import Exception
|
|
from exceptions import Exception
|
|
|
import sys
|
|
import sys
|
|
|
-import traceback
|
|
|
|
|
|
|
+import types
|
|
|
|
|
+
|
|
|
|
|
+notify = directNotify.newCategory("ExceptionVarDump")
|
|
|
|
|
|
|
|
reentry = 0
|
|
reentry = 0
|
|
|
|
|
|
|
@@ -11,30 +14,33 @@ def _varDump__init__(self, *args, **kArgs):
|
|
|
if reentry > 0:
|
|
if reentry > 0:
|
|
|
return
|
|
return
|
|
|
reentry += 1
|
|
reentry += 1
|
|
|
|
|
+ # frame zero is this frame
|
|
|
f = 1
|
|
f = 1
|
|
|
self._savedExcString = None
|
|
self._savedExcString = None
|
|
|
self._savedStackFrames = []
|
|
self._savedStackFrames = []
|
|
|
while True:
|
|
while True:
|
|
|
try:
|
|
try:
|
|
|
frame = sys._getframe(f)
|
|
frame = sys._getframe(f)
|
|
|
|
|
+ except ValueError, e:
|
|
|
|
|
+ break
|
|
|
|
|
+ else:
|
|
|
f += 1
|
|
f += 1
|
|
|
self._savedStackFrames.append(frame)
|
|
self._savedStackFrames.append(frame)
|
|
|
- except:
|
|
|
|
|
- break
|
|
|
|
|
self._moved__init__(*args, **kArgs)
|
|
self._moved__init__(*args, **kArgs)
|
|
|
reentry -= 1
|
|
reentry -= 1
|
|
|
|
|
|
|
|
sReentry = 0
|
|
sReentry = 0
|
|
|
|
|
|
|
|
-def _varDump__str__(self, *args, **kArgs):
|
|
|
|
|
|
|
+def _varDump__print(exc):
|
|
|
global sReentry
|
|
global sReentry
|
|
|
|
|
+ global notify
|
|
|
if sReentry > 0:
|
|
if sReentry > 0:
|
|
|
return
|
|
return
|
|
|
sReentry += 1
|
|
sReentry += 1
|
|
|
- if not self._savedExcString:
|
|
|
|
|
|
|
+ if not exc._savedExcString:
|
|
|
s = ''
|
|
s = ''
|
|
|
foundRun = False
|
|
foundRun = False
|
|
|
- for frame in reversed(self._savedStackFrames):
|
|
|
|
|
|
|
+ for frame in reversed(exc._savedStackFrames):
|
|
|
filename = frame.f_code.co_filename
|
|
filename = frame.f_code.co_filename
|
|
|
codename = frame.f_code.co_name
|
|
codename = frame.f_code.co_name
|
|
|
if not foundRun and codename != 'run':
|
|
if not foundRun and codename != 'run':
|
|
@@ -48,17 +54,59 @@ def _varDump__str__(self, *args, **kArgs):
|
|
|
obj = locals[var]
|
|
obj = locals[var]
|
|
|
rep = fastRepr(obj)
|
|
rep = fastRepr(obj)
|
|
|
s += '::%s = %s\n' % (var, rep)
|
|
s += '::%s = %s\n' % (var, rep)
|
|
|
- self._savedExcString = s
|
|
|
|
|
- self._savedStackFrames = None
|
|
|
|
|
- notify = directNotify.newCategory("ExceptionVarDump")
|
|
|
|
|
- notify.info(self._savedExcString)
|
|
|
|
|
- str = self._moved__str__(*args, **kArgs)
|
|
|
|
|
|
|
+ exc._savedExcString = s
|
|
|
|
|
+ exc._savedStackFrames = None
|
|
|
|
|
+ notify.info(exc._savedExcString)
|
|
|
sReentry -= 1
|
|
sReentry -= 1
|
|
|
- return str
|
|
|
|
|
|
|
+
|
|
|
|
|
+oldExcepthook = None
|
|
|
|
|
+# store these values here so that Task.py can always reliably access these values
|
|
|
|
|
+# from its main exception handler
|
|
|
|
|
+wantVariableDump = False
|
|
|
|
|
+dumpOnExceptionInit = False
|
|
|
|
|
+
|
|
|
|
|
+def _excepthookDumpVars(eType, eValue, traceback):
|
|
|
|
|
+ s = 'DUMPING STACK FRAME VARIABLES'
|
|
|
|
|
+ tb = traceback
|
|
|
|
|
+ #import pdb;pdb.set_trace()
|
|
|
|
|
+ foundRun = False
|
|
|
|
|
+ while tb is not None:
|
|
|
|
|
+ frame = tb.tb_frame
|
|
|
|
|
+ code = frame.f_code
|
|
|
|
|
+ tb = tb.tb_next
|
|
|
|
|
+ # skip everything before the 'run' method, those frames have lots of
|
|
|
|
|
+ # not-useful information
|
|
|
|
|
+ if not foundRun:
|
|
|
|
|
+ if code.co_name == 'run':
|
|
|
|
|
+ foundRun = True
|
|
|
|
|
+ else:
|
|
|
|
|
+ continue
|
|
|
|
|
+ s += '\n File "%s", line %s, in %s' % (
|
|
|
|
|
+ code.co_filename, frame.f_lineno, code.co_name)
|
|
|
|
|
+ for name, val in frame.f_locals.iteritems():
|
|
|
|
|
+ r = fastRepr(val)
|
|
|
|
|
+ if type(r) is types.StringType:
|
|
|
|
|
+ r = r.replace('\n', '\\n')
|
|
|
|
|
+ s += '\n %s=%s' % (name, r)
|
|
|
|
|
+ s += '\n'
|
|
|
|
|
+ notify.info(s)
|
|
|
|
|
+ oldExcepthook(eType, eValue, traceback)
|
|
|
|
|
|
|
|
def install():
|
|
def install():
|
|
|
- if not hasattr(Exception, '_moved__init__'):
|
|
|
|
|
- Exception._moved__init__ = Exception.__init__
|
|
|
|
|
- Exception.__init__ = _varDump__init__
|
|
|
|
|
- Exception._moved__str__ = Exception.__str__
|
|
|
|
|
- Exception.__str__ = _varDump__str__
|
|
|
|
|
|
|
+ global oldExcepthook
|
|
|
|
|
+ global wantVariableDump
|
|
|
|
|
+ global dumpOnExceptionInit
|
|
|
|
|
+
|
|
|
|
|
+ wantVariableDump = True
|
|
|
|
|
+ dumpOnExceptionInit = config.GetBool('variable-dump-on-exception-init', 0)
|
|
|
|
|
+ if dumpOnExceptionInit:
|
|
|
|
|
+ # this mode doesn't completely work because exception objects
|
|
|
|
|
+ # thrown by the interpreter don't get created until the
|
|
|
|
|
+ # stack has been unwound and an except block has been reached
|
|
|
|
|
+ if not hasattr(Exception, '_moved__init__'):
|
|
|
|
|
+ Exception._moved__init__ = Exception.__init__
|
|
|
|
|
+ Exception.__init__ = _varDump__init__
|
|
|
|
|
+ else:
|
|
|
|
|
+ if sys.excepthook is not _excepthookDumpVars:
|
|
|
|
|
+ oldExcepthook = sys.excepthook
|
|
|
|
|
+ sys.excepthook = _excepthookDumpVars
|