📄 debuggerharness.py
字号:
tp, val, tb = sys.exc_info()
output = cStringIO.StringIO()
traceback.print_exception(tp, val, tb, file=output)
return output.getvalue()
def attempt_introspection(self, frame_message, chain):
try:
frame = self.message_frame_dict[frame_message]
if frame:
name = chain.pop(0)
if name == 'globals':
item = frame.f_globals
elif name == 'locals':
item = frame.f_locals
for name in chain:
item = self.getNextItem(item, name)
return self.get_introspection_document(item, name)
except:
tp, val, tb = sys.exc_info()
traceback.print_exception(tp, val, tb)
return self.get_empty_introspection_document()
def getNextItem(self, link, identifier):
tp = type(link)
if self.isTupleized(identifier):
return self.deTupleize(link, identifier)
else:
if tp == types.DictType or tp == types.DictProxyType:
return link[identifier]
else:
if hasattr(link, identifier):
return getattr(link, identifier)
if _VERBOSE or True: print "Failed to find link ", identifier, " on thing: ", self.saferepr(link), " of type ", repr(type(link))
return None
def isPrimitive(self, item):
tp = type(item)
return tp is types.IntType or tp is types.LongType or tp is types.FloatType \
or tp is types.BooleanType or tp is types.ComplexType \
or tp is types.StringType
def isTupleized(self, value):
return value.count('[')
def deTupleize(self, link, string1):
try:
start = string1.find('[')
end = string1.find(']')
num = int(string1[start+1:end])
return link[num]
except:
tp,val,tb = sys.exc_info()
if _VERBOSE: print "Got exception in deTupleize: ", val
return None
def wrapAndCompress(self, stringDoc):
import bz2
return xmlrpclib.Binary(bz2.compress(stringDoc))
def get_empty_introspection_document(self):
doc = getDOMImplementation().createDocument(None, "replacement", None)
return self.wrapAndCompress(doc.toxml())
def get_watch_document(self, item, identifier):
doc = getDOMImplementation().createDocument(None, "watch", None)
top_element = doc.documentElement
self.addAny(top_element, identifier, item, doc, 2)
return self.wrapAndCompress(doc.toxml())
def get_introspection_document(self, item, identifier):
doc = getDOMImplementation().createDocument(None, "replacement", None)
top_element = doc.documentElement
self.addAny(top_element, identifier, item, doc, 2)
return self.wrapAndCompress(doc.toxml())
def get_exception_document(self, name, tp, val, tb):
stack = traceback.format_exception(tp, val, tb)
wholeStack = ""
for line in stack:
wholeStack += line
doc = getDOMImplementation().createDocument(None, "watch", None)
top_element = doc.documentElement
item_node = doc.createElement("dict_nv_element")
item_node.setAttribute('value', wholeStack)
item_node.setAttribute('name', str(name))
top_element.appendChild(item_node)
cantIntro = [types.FunctionType,
types.LambdaType,
types.UnicodeType,
types.StringType,
types.NoneType,
types.IntType,
types.LongType,
types.FloatType,
types.BooleanType]
def addAny(self, top_element, name, item, doc, ply):
tp = type(item)
if tp in DebuggerHarness.cantIntro or ply < 1:
self.addNode(top_element,name, item, doc)
elif tp is types.TupleType or tp is types.ListType:
self.addTupleOrList(top_element, name, item, doc, ply - 1)
elif tp is types.DictType or tp is types.DictProxyType:
self.addDict(top_element, name, item, doc, ply -1)
elif inspect.ismodule(item):
self.addModule(top_element, name, item, doc, ply -1)
elif inspect.isclass(item) or tp is types.InstanceType:
self.addClass(top_element, name, item, doc, ply -1)
elif hasattr(item, '__dict__'):
self.addDictAttr(top_element, name, item, doc, ply -1)
else:
self.addNode(top_element,name, item, doc)
def canIntrospect(self, item):
tp = type(item)
if tp in DebuggerHarness.cantIntro:
return False
elif tp is types.TupleType or tp is types.ListType:
return len(item) > 0
elif tp is types.DictType or tp is types.DictProxyType:
return len(item) > 0
elif inspect.ismodule(item):
return True
elif inspect.isclass(item) or tp is types.InstanceType:
if hasattr(item, '__dict__'):
return True
elif hasattr(item, '__name__'):
return True
elif hasattr(item, '__module__'):
return True
elif hasattr(item, '__doc__'):
return True
else:
return False
elif hasattr(item, '__dict__'):
return len(item.__dict__) > 0
else:
return False
def addNode(self, parent_node, name, item, document):
item_node = document.createElement("dict_nv_element")
item_node.setAttribute('value', self.saferepr(item))
item_node.setAttribute('name', str(name))
introVal = str(self.canIntrospect(item))
item_node.setAttribute('intro', str(introVal))
parent_node.appendChild(item_node)
def addTupleOrList(self, top_node, name, tupple, doc, ply):
tupleNode = doc.createElement('tuple')
tupleNode.setAttribute('name', str(name))
tupleNode.setAttribute('value', self.saferepr(tupple))
top_node.appendChild(tupleNode)
count = 0
for item in tupple:
self.addAny(tupleNode, name +'[' + str(count) + ']',item, doc, ply -1)
count += 1
def addDictAttr(self, root_node, name, thing, document, ply):
dict_node = document.createElement('thing')
dict_node.setAttribute('name', name)
dict_node.setAttribute('value', self.saferepr(thing))
root_node.appendChild(dict_node)
self.addDict(dict_node, '', thing.__dict__, document, ply) # Not decreminting ply
def addDict(self, root_node, name, dict, document, ply):
if name != '':
dict_node = document.createElement('dict')
dict_node.setAttribute('name', name)
dict_node.setAttribute('value', self.saferepr(dict))
root_node.appendChild(dict_node)
else:
dict_node = root_node
for key in dict.keys():
strkey = str(key)
try:
value = dict[key]
self.addAny(dict_node, strkey, value, document, ply-1)
except:
if _VERBOSE:
tp,val,tb=sys.exc_info()
print "Error recovering key: ", str(key), " from node ", str(name), " Val = ", str(val)
traceback.print_exception(tp, val, tb)
def addClass(self, root_node, name, class_item, document, ply):
item_node = document.createElement('class')
item_node.setAttribute('name', str(name))
item_node.setAttribute('value', self.saferepr(class_item))
root_node.appendChild(item_node)
try:
if hasattr(class_item, '__dict__'):
self.addDict(item_node, '', class_item.__dict__, document, ply -1)
except:
tp,val,tb=sys.exc_info()
if _VERBOSE:
traceback.print_exception(tp, val, tb)
try:
if hasattr(class_item, '__name__'):
self.addAny(item_node,'__name__',class_item.__name__, document, ply -1)
except:
tp,val,tb=sys.exc_info()
if _VERBOSE:
traceback.print_exception(tp, val, tb)
try:
if hasattr(class_item, '__module__'):
self.addAny(item_node, '__module__', class_item.__module__, document, ply -1)
except:
tp,val,tb=sys.exc_info()
if _VERBOSE:
traceback.print_exception(tp, val, tb)
try:
if hasattr(class_item, '__doc__'):
self.addAny(item_node, '__doc__', class_item.__doc__, document, ply -1)
except:
tp,val,tb=sys.exc_info()
if _VERBOSE:
traceback.print_exception(tp, val, tb)
try:
if hasattr(class_item, '__bases__'):
self.addAny(item_node, '__bases__', class_item.__bases__, document, ply -1)
except:
tp,val,tb=sys.exc_info()
if _VERBOSE:
traceback.print_exception(tp, val, tb)
def addModule(self, root_node, name, module_item, document, ply):
item_node = document.createElement('module')
item_node.setAttribute('name', str(name))
item_node.setAttribute('value', self.saferepr(module_item))
root_node.appendChild(item_node)
try:
if hasattr(module_item, '__file__'):
self.addAny(item_node, '__file__', module_item.__file__, document, ply -1)
except:
pass
try:
if hasattr(module_item, '__doc__'):
self.addAny(item_node,'__doc__', module_item.__doc__, document, ply -1)
except:
pass
def getFrameXML(self, base_frame):
self.frame_stack = []
frame = base_frame
while frame is not None:
if((frame.f_code.co_filename.count('DebuggerHarness.py') == 0) or _DEBUG_DEBUGGER):
self.frame_stack.append(frame)
frame = frame.f_back
self.frame_stack.reverse()
self.message_frame_dict = {}
doc = getDOMImplementation().createDocument(None, "stack", None)
top_element = doc.documentElement
numberFrames = len(self.frame_stack)
for index in range(numberFrames):
frame = self.frame_stack[index]
message = self._adb.frame2message(frame)
# We include globals and locals only for the last frame as an optimization for cases
# where there are a lot of frames.
self.addFrame(frame, top_element, doc, includeContent=(index == numberFrames - 1))
return doc.toxml()
def addFrame(self, frame, root_element, document, includeContent=False):
frameNode = document.createElement('frame')
root_element.appendChild(frameNode)
code = frame.f_code
filename = code.co_filename
frameNode.setAttribute('file', str(filename))
frameNode.setAttribute('line', str(frame.f_lineno))
message = self._adb.frame2message(frame)
frameNode.setAttribute('message', message)
self.message_frame_dict[message] = frame
if includeContent:
self.addDict(frameNode, "locals", frame.f_locals, document, 2)
self.addNode(frameNode, "globals", frame.f_globals, document)
def request_frame_document(self, message):
frame = self.message_frame_dict[message]
doc = getDOMImplementation().createDocument(None, "stack", None)
top_element = doc.documentElement
if frame:
self.addFrame(frame, top_element, doc, includeContent=True)
return xmlrpclib.Binary(bz2.compress(doc.toxml()))
def getRepr(self, varName, globals, locals):
try:
return repr(eval(varName, globals, locals))
except:
return 'Error: Could not recover value.'
def saferepr(self, thing):
try:
try:
return repr(thing)
except:
return str(type(thing))
except:
tp, val, tb = sys.exc_info()
#traceback.print_exception(tp, val, tb)
return repr(val)
# The debugger calls this method when it reaches a breakpoint.
def interaction(self, message, frame, info):
if _VERBOSE:
print 'hit debug side interaction'
self._adb._userBreak = False
self._currentFrame = frame
done = False
while not done:
try:
xml = self.getFrameXML(frame)
arg = xmlrpclib.Binary(bz2.compress(xml))
if _VERBOSE:
print '============== calling gui side interaction============'
self._guiServer.interaction(xmlrpclib.Binary(message), arg, info)
if _VERBOSE:
print 'after interaction'
done = True
except:
tp, val, tb = sys.exc_info()
if True or _VERBOSE:
print 'Error contacting GUI server!: '
try:
traceback.print_exception(tp, val, tb)
except:
print "Exception printing traceback",
tp, val, tb = sys.exc_info()
traceback.print_exception(tp, val, tb)
done = False
# Block while waiting to be called back from the GUI. Eventually, self._wait will
# be set false by a function on this side. Seems pretty lame--I'm surprised it works.
self.waitForRPC()
def waitForRPC(self):
self._wait = True
while self._wait :
try:
if _VERBOSE:
print "+++ in harness wait for rpc, before handle_request"
self._server.handle_request()
if _VERBOSE:
print "+++ in harness wait for rpc, after handle_request"
except:
if _VERBOSE:
tp, val, tb = sys.exc_info()
print "Got waitForRpc exception : ", repr(tp), ": ", val
#time.sleep(0.1)
def set_step(self):
self._adb.set_step()
self._wait = False
return ""
def set_continue(self):
self._adb.set_continue()
self._wait = False
return ""
def set_next(self):
self._adb.set_next(self._currentFrame)
self._wait = False
return ""
def set_return(self):
self._adb.set_return(self._currentFrame)
self._wait = False
return ""
if __name__ == '__main__':
try:
harness = DebuggerHarness()
harness.run()
harness.do_exit(kill=True)
except SystemExit:
print "Exiting..."
except:
tp, val, tb = sys.exc_info()
traceback.print_exception(tp, val, tb)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -