📄 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 + -