X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f780e48af479e7bf9a07eaaa1ab6b41f1ffb17b..b0d8bfa6cd4042d3ea8680ad0145f79e3cb15268:/wxPython/samples/ide/activegrid/tool/DebuggerHarness.py?ds=inline diff --git a/wxPython/samples/ide/activegrid/tool/DebuggerHarness.py b/wxPython/samples/ide/activegrid/tool/DebuggerHarness.py index a12b8e579b..63452dcb9d 100644 --- a/wxPython/samples/ide/activegrid/tool/DebuggerHarness.py +++ b/wxPython/samples/ide/activegrid/tool/DebuggerHarness.py @@ -22,6 +22,8 @@ import inspect from xml.dom.minidom import getDOMImplementation import atexit import pickle +import cStringIO +import bz2 if sys.platform.startswith("win"): import win32api @@ -189,7 +191,7 @@ class Adb(bdb.Bdb): return "" def stop_here(self, frame): - if( self._userBreak ): + if self._userBreak: return True @@ -269,6 +271,7 @@ class BreakListenerThread(threading.Thread): if _VERBOSE: print "Before calling server close on breakpoint server" self._server.server_close() if _VERBOSE: print "Calling server close on breakpoint server" + self._server = None class DebuggerHarness(object): @@ -311,8 +314,11 @@ class DebuggerHarness(object): self._server.register_function(self.clear_breakpoint) self._server.register_function(self.set_all_breakpoints) self._server.register_function(self.attempt_introspection) + self._server.register_function(self.execute_in_frame) self._server.register_function(self.add_watch) + self._server.register_function(self.request_frame_document) + self.frame_stack = [] self.message_frame_dict = {} self.introspection_list = [] atexit.register(self.do_exit) @@ -363,7 +369,29 @@ class DebuggerHarness(object): tp, val, tb = sys.exc_info() return self.get_exception_document(tp, val, tb) return "" - + + def execute_in_frame(self, frame_message, command): + frame = self.message_frame_dict[frame_message] + output = cStringIO.StringIO() + out = sys.stdout + err = sys.stderr + sys.stdout = output + sys.stderr = output + try: + code = compile(command, '', 'single') + exec code in frame.f_globals, frame.f_locals + return output.getvalue() + sys.stdout = out + sys.stderr = err + except: + sys.stdout = out + sys.stderr = err + + 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] @@ -446,11 +474,22 @@ class DebuggerHarness(object): 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 ply < 1: - self.addNode(top_element,name, self.saferepr(item), doc) + + 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: @@ -459,108 +498,95 @@ class DebuggerHarness(object): 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) elif hasattr(item, '__dict__'): - self.addDict(top_element, name, item.__dict__, doc, ply -1) + self.addDictAttr(top_element, name, item, doc, ply -1) else: - self.addNode(top_element,name, self.saferepr(item), doc) + 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', str(type(tupple))) + 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 getFrameXML(self, base_frame): - doc = getDOMImplementation().createDocument(None, "stack", None) - top_element = doc.documentElement - - stack = [] - frame = base_frame - while frame is not None: - if((frame.f_code.co_filename.count('DebuggerHarness.py') == 0) or _DEBUG_DEBUGGER): - stack.append(frame) - frame = frame.f_back - stack.reverse() - self.message_frame_dict = {} - for f in stack: - self.addFrame(f,top_element, doc) - return doc.toxml() - - def addFrame(self, frame, root_element, document): - 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) - #print "Frame: %s %s %s" %(message, frame.f_lineno, filename) - self.message_frame_dict[message] = frame - self.addDict(frameNode, "locals", frame.f_locals, document, 2) - self.addNode(frameNode, "globals", "", document) - - def getRepr(self, varName, globals, locals): - try: - return repr(eval(varName, globals, locals)) - except: - return 'Error: Could not recover value.' - - def addNode(self, parent_node, name, value, document): - item_node = document.createElement("dict_nv_element") - item_node.setAttribute('value', self.saferepr(value)) - item_node.setAttribute('name', str(name)) - parent_node.appendChild(item_node) - def addDictAttr(self, root_node, name, thing, document, ply): dict_node = document.createElement('thing') - root_node.setAttribute('name', name) - root_node.setAttribute('value', str(type(dict)) + " add attr") - self.addDict(root_node, name, thing.__dict__, document, ply) # Not decreminting ply - - def saferepr(self, thing): - try: - return repr(thing) - except: - tp, val, tb = sys.exc_info() - return repr(val) - - def addDict(self, root_node, name, dict, document, ply): - dict_node = document.createElement('dict') dict_node.setAttribute('name', name) - dict_node.setAttribute('value', str(type(dict)) + " add dict") + 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: - self.addAny(dict_node, strkey, dict[key], document, ply-1) + value = dict[key] + self.addAny(dict_node, strkey, value, document, ply-1) except: - tp,val,tb=sys.exc_info() 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) - self.addAny(dict_node, strkey, "Exception getting " + str(name) + "[" + strkey + "]: " + str(val), document, ply -1) 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.addAny(item_node, '__dict__', class_item.__dict__, document, ply -1) + 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) - self.addAny(item_node, '__dict__', "Exception getting __dict__: " + str(val), document, ply -1) try: if hasattr(class_item, '__name__'): self.addAny(item_node,'__name__',class_item.__name__, document, ply -1) @@ -568,7 +594,6 @@ class DebuggerHarness(object): tp,val,tb=sys.exc_info() if _VERBOSE: traceback.print_exception(tp, val, tb) - self.addAny(item_node,'__name__',"Exception getting class.__name__: " + val, document, ply -1) try: if hasattr(class_item, '__module__'): self.addAny(item_node, '__module__', class_item.__module__, document, ply -1) @@ -576,7 +601,6 @@ class DebuggerHarness(object): tp,val,tb=sys.exc_info() if _VERBOSE: traceback.print_exception(tp, val, tb) - self.addAny(item_node, '__module__', "Exception getting class.__module__: " + val, document, ply -1) try: if hasattr(class_item, '__doc__'): self.addAny(item_node, '__doc__', class_item.__doc__, document, ply -1) @@ -584,7 +608,6 @@ class DebuggerHarness(object): tp,val,tb=sys.exc_info() if _VERBOSE: traceback.print_exception(tp, val, tb) - self.addAny(item_node, '__doc__', "Exception getting class.__doc__: " + val, document, ply -1) try: if hasattr(class_item, '__bases__'): self.addAny(item_node, '__bases__', class_item.__bases__, document, ply -1) @@ -592,11 +615,11 @@ class DebuggerHarness(object): tp,val,tb=sys.exc_info() if _VERBOSE: traceback.print_exception(tp, val, tb) - self.addAny(item_node, '__bases__', "Exception getting class.__bases__: " + val, document, ply -1) 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__'): @@ -609,17 +632,80 @@ class DebuggerHarness(object): 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._userBreak = False + self._adb._userBreak = False self._currentFrame = frame done = False while not done: try: - import bz2 xml = self.getFrameXML(frame) arg = xmlrpclib.Binary(bz2.compress(xml)) if _VERBOSE: @@ -683,6 +769,7 @@ if __name__ == '__main__': try: harness = DebuggerHarness() harness.run() + harness.do_exit(kill=True) except SystemExit: print "Exiting..." except: