import pdb import sys import linecache import inspect import os class Dumper: def __init__(self): pass def updateData(self, args): self.expandedINames = set(args.get("expanded", [])) self.typeformats = args.get("typeformats", {}) self.formats = args.get("formats", {}) self.watchers = args.get("watchers", {}) self.output = "data={" # self.handleListModules() # self.handleListSymbols(expanded) # Trigger error to get a backtrace. frame = None #self.warn("frame: %s" % frame) try: raise ZeroDivisionError except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame.f_back limit = 30 n = 0 isActive = False while frame is not None and n < limit: #self.warn("frame: %s" % frame.f_locals.keys()) lineno = frame.f_lineno code = frame.f_code filename = code.co_filename name = code.co_name if isActive: linecache.checkcache(filename) line = linecache.getline(filename, lineno, frame.f_globals) self.dumpFrame(frame) if name == "": isActive = False if name == "trace_dispatch": isActive = True frame = frame.f_back n = n + 1 #sys.stdout.flush() self.output += '}' sys.stdout.write(self.output) def put(self, value): #sys.stdout.write(value) self.output += value def putField(self, name, value): self.put('%s="%s",' % (name, value)) def putItemCount(self, count): self.put('value="<%s items>",' % count) def putEllipsis(self): self.put('{name="",value="",type="",numchild="0"},') def cleanType(self, type): t = str(type) if t.startswith(""): t = t[7:-2] if t.startswith(""): t = t[8:-2] return t def putType(self, type, priority = 0): self.putField("type", self.cleanType(type)) def putAddress(self, addr): self.put('addr="%s",' % cleanAddress(addr)) def putNumChild(self, numchild): self.put('numchild="%s",' % numchild) def putValue(self, value, encoding = None, priority = 0): self.putField("value", value) def putName(self, name): self.put('name="%s",' % name) def isExpanded(self, iname): #self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames)) if iname.startswith("None"): raise "Illegal iname '%s'" % iname #self.warn(" --> %s" % (iname in self.expandedINames)) return iname in self.expandedINames def isExpandedIName(self, iname): return iname in self.expandedINames def itemFormat(self, item): format = self.formats.get(str(cleanAddress(item.value.address))) if format is None: format = self.typeformats.get(self.stripClassTag(str(item.value.type))) return format def dumpFrame(self, frame): for var in frame.f_locals.keys(): if var == "__file__": continue #if var == "__name__": # continue if var == "__package__": continue if var == "qdebug": continue if var != '__builtins__': value = frame.f_locals[var] self.dumpValue(value, var, "local.%s" % var) def dumpValue(self, value, name, iname): t = type(value) tt = self.cleanType(t) if tt == "module" or tt == "function": return if str(value).startswith(" 1: v = "@" + v[p + 11:-1] self.putValue(v) if self.isExpanded(iname): self.put("children=[") for child in dir(value): if child == "__dict__": continue if child == "__doc__": continue if child == "__module__": continue attr = getattr(value, child) if callable(attr): continue try: self.dumpValue(attr, child, "%s.%s" % (iname, child)) except: pass self.put("],") self.put("},") def warn(self, msg): self.putField("warning", msg) def handleListModules(self): self.put("modules=["); for name in sys.modules: self.put("{") self.putName(name) self.putValue(sys.modules[name]) self.put("},") self.put("]") #sys.stdout.flush() def handleListSymbols(self, module): #self.put("symbols=%s" % dir(sys.modules[module])) self.put("symbols=["); for name in sys.modules: self.put("{") self.putName(name) #self.putValue(sys.modules[name]) self.put("},") self.put("]") #sys.stdout.flush() def stackListFrames(self, args): #isNativeMixed = int(args.get('nativeMixed', 0)) #result = 'stack={current-thread="%s"' % thread.GetThreadID() result = 'stack={current-thread="%s"' % 1 result += ',frames=[' level = 0 for frame in inspect.stack(): l = [i for i in frame] fileName = l[1] (head, tail) = os.path.split(fileName) if tail in ("pdbbridge.py", "bdb.py", "pdb.py", "cmd.py", ""): continue level += 1 result += '{' result += 'a0="%s",' % l[0] result += 'file="%s",' % fileName result += 'line="%s",' % l[2] result += 'a3="%s",' % l[3] result += 'a4="%s",' % l[4] result += 'a5="%s",' % l[5] result += 'level="%s",' % level result += '}' result += ']' #result += ',hasmore="%d"' % isLimited #result += ',limit="%d"' % limit result += '}' self.report(result) def report(self, stuff): sys.stdout.write("@\n" + stuff + "@\n") sys.stdout.flush() def qdebug(options = None, expanded = None, typeformats = None, individualformats = None, watchers = None): sys.stdout.write("\n(Pdb)\n") sys.stdout.flush() theDumper = Dumper()