forked from qt-creator/qt-creator
Debugger: Some dumper code cosmetics
Mostly quotes, remove some unneeded comments, ... Change-Id: Ie3f410ac84e6cfe48e7971af948326abc21f2554 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -48,13 +48,13 @@ def safePrint(output):
|
||||
try:
|
||||
print(output)
|
||||
except:
|
||||
out = ""
|
||||
out = ''
|
||||
for c in output:
|
||||
cc = ord(c)
|
||||
if cc > 127:
|
||||
out += "\\\\%d" % cc
|
||||
out += '\\\\%d' % cc
|
||||
elif cc < 0:
|
||||
out += "\\\\%d" % (cc + 256)
|
||||
out += '\\\\%d' % (cc + 256)
|
||||
else:
|
||||
out += c
|
||||
print(out)
|
||||
@@ -80,7 +80,7 @@ def registerCommand(name, func):
|
||||
# Just convienience for 'python print ...'
|
||||
class PPCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super(PPCommand, self).__init__("pp", gdb.COMMAND_OBSCURE)
|
||||
super(PPCommand, self).__init__('pp', gdb.COMMAND_OBSCURE)
|
||||
def invoke(self, args, from_tty):
|
||||
print(eval(args))
|
||||
|
||||
@@ -89,7 +89,7 @@ PPCommand()
|
||||
# Just convienience for 'python print gdb.parse_and_eval(...)'
|
||||
class PPPCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super(PPPCommand, self).__init__("ppp", gdb.COMMAND_OBSCURE)
|
||||
super(PPPCommand, self).__init__('ppp', gdb.COMMAND_OBSCURE)
|
||||
def invoke(self, args, from_tty):
|
||||
print(gdb.parse_and_eval(args))
|
||||
|
||||
@@ -100,20 +100,20 @@ def scanStack(p, n):
|
||||
p = int(p)
|
||||
r = []
|
||||
for i in xrange(n):
|
||||
f = gdb.parse_and_eval("{void*}%s" % p)
|
||||
m = gdb.execute("info symbol %s" % f, to_string=True)
|
||||
if not m.startswith("No symbol matches"):
|
||||
f = gdb.parse_and_eval('{void*}%s' % p)
|
||||
m = gdb.execute('info symbol %s' % f, to_string=True)
|
||||
if not m.startswith('No symbol matches'):
|
||||
r.append(m)
|
||||
p += f.type.sizeof
|
||||
return r
|
||||
|
||||
class ScanStackCommand(gdb.Command):
|
||||
def __init__(self):
|
||||
super(ScanStackCommand, self).__init__("scanStack", gdb.COMMAND_OBSCURE)
|
||||
super(ScanStackCommand, self).__init__('scanStack', gdb.COMMAND_OBSCURE)
|
||||
def invoke(self, args, from_tty):
|
||||
if len(args) == 0:
|
||||
args = 20
|
||||
safePrint(scanStack(gdb.parse_and_eval("$sp"), int(args)))
|
||||
safePrint(scanStack(gdb.parse_and_eval('$sp'), int(args)))
|
||||
|
||||
ScanStackCommand()
|
||||
|
||||
@@ -134,7 +134,7 @@ class PlainDumper:
|
||||
printer = self.printer.gen_printer(value)
|
||||
except:
|
||||
printer = self.printer.invoke(value)
|
||||
lister = getattr(printer, "children", None)
|
||||
lister = getattr(printer, 'children', None)
|
||||
children = [] if lister is None else list(lister())
|
||||
d.putType(self.printer.name)
|
||||
val = printer.to_string()
|
||||
@@ -152,16 +152,16 @@ class PlainDumper:
|
||||
d.putSubItem(child[0], child[1])
|
||||
|
||||
def importPlainDumpers(args):
|
||||
if args == "off":
|
||||
if args == 'off':
|
||||
try:
|
||||
gdb.execute("disable pretty-printer .* .*")
|
||||
gdb.execute('disable pretty-printer .* .*')
|
||||
except:
|
||||
# Might occur in non-ASCII directories
|
||||
warn("COULD NOT DISABLE PRETTY PRINTERS")
|
||||
warn('COULD NOT DISABLE PRETTY PRINTERS')
|
||||
else:
|
||||
theDumper.importPlainDumpers()
|
||||
|
||||
registerCommand("importPlainDumpers", importPlainDumpers)
|
||||
registerCommand('importPlainDumpers', importPlainDumpers)
|
||||
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ class OutputSafer:
|
||||
|
||||
def __exit__(self, exType, exValue, exTraceBack):
|
||||
if self.d.passExceptions and not exType is None:
|
||||
showException("OUTPUTSAFER", exType, exValue, exTraceBack)
|
||||
showException('OUTPUTSAFER', exType, exValue, exTraceBack)
|
||||
self.d.output = self.savedOutput
|
||||
else:
|
||||
self.savedOutput.extend(self.d.output)
|
||||
@@ -206,7 +206,7 @@ class Dumper(DumperBase):
|
||||
self.setVariableFetchingOptions(args)
|
||||
|
||||
def fromFrameValue(self, nativeValue):
|
||||
#warn("FROM FRAME VALUE: %s" % nativeValue.address)
|
||||
#warn('FROM FRAME VALUE: %s' % nativeValue.address)
|
||||
val = nativeValue
|
||||
try:
|
||||
val = nativeValue.cast(nativeValue.dynamic_type)
|
||||
@@ -215,14 +215,14 @@ class Dumper(DumperBase):
|
||||
return self.fromNativeValue(val)
|
||||
|
||||
def fromNativeValue(self, nativeValue):
|
||||
#warn("FROM NATIVE VALUE: %s" % nativeValue.address)
|
||||
#warn('FROM NATIVE VALUE: %s' % nativeValue)
|
||||
self.check(isinstance(nativeValue, gdb.Value))
|
||||
nativeType = nativeValue.type
|
||||
code = nativeType.code
|
||||
if code == gdb.TYPE_CODE_REF:
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified(), nativeValue)
|
||||
val = self.createReferenceValue(toInteger(nativeValue.address), targetType)
|
||||
#warn("CREATED REF: %s" % val)
|
||||
#warn('CREATED REF: %s' % val)
|
||||
return val
|
||||
if code == gdb.TYPE_CODE_PTR:
|
||||
try:
|
||||
@@ -231,14 +231,14 @@ class Dumper(DumperBase):
|
||||
nativeTargetValue = None
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified(), nativeTargetValue)
|
||||
val = self.createPointerValue(toInteger(nativeValue), targetType)
|
||||
#warn("CREATED PTR 1: %s" % val)
|
||||
#warn('CREATED PTR 1: %s' % val)
|
||||
if not nativeValue.address is None:
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
#warn("CREATED PTR 2: %s" % val)
|
||||
#warn('CREATED PTR 2: %s' % val)
|
||||
return val
|
||||
if code == gdb.TYPE_CODE_TYPEDEF:
|
||||
targetType = nativeType.strip_typedefs().unqualified()
|
||||
#warn("TARGET TYPE: %s" % targetType)
|
||||
#warn('TARGET TYPE: %s' % targetType)
|
||||
if targetType.code == gdb.TYPE_CODE_ARRAY:
|
||||
val = self.Value(self)
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
@@ -246,7 +246,7 @@ class Dumper(DumperBase):
|
||||
# Cast may fail (e.g for arrays, see test for Bug5799)
|
||||
val = self.fromNativeValue(nativeValue.cast(targetType))
|
||||
val.type = self.fromNativeType(nativeType, nativeValue)
|
||||
#warn("CREATED TYPEDEF: %s" % val)
|
||||
#warn('CREATED TYPEDEF: %s' % val)
|
||||
return val
|
||||
|
||||
val = self.Value(self)
|
||||
@@ -254,7 +254,7 @@ class Dumper(DumperBase):
|
||||
val.laddress = toInteger(nativeValue.address)
|
||||
else:
|
||||
size = nativeType.sizeof
|
||||
chars = self.lookupNativeType("unsigned char")
|
||||
chars = self.lookupNativeType('unsigned char')
|
||||
y = nativeValue.cast(chars.array(0, int(nativeType.sizeof - 1)))
|
||||
buf = bytearray(struct.pack('x' * size))
|
||||
for i in range(size):
|
||||
@@ -400,7 +400,7 @@ class Dumper(DumperBase):
|
||||
|
||||
def nativeStructAlignment(self, nativeType):
|
||||
self.preping('align ' + str(nativeType))
|
||||
#warn("NATIVE ALIGN FOR %s" % nativeType.name)
|
||||
#warn('NATIVE ALIGN FOR %s' % nativeType.name)
|
||||
def handleItem(nativeFieldType, align):
|
||||
a = self.fromNativeType(nativeFieldType).alignment()
|
||||
return a if a > align else align
|
||||
@@ -460,7 +460,7 @@ class Dumper(DumperBase):
|
||||
return None
|
||||
|
||||
def listMembers(self, nativeType, nativeValue):
|
||||
#warn("LISTING MEMBERS OF %s" % nativeType)
|
||||
#warn('LISTING MEMBERS OF %s' % nativeType)
|
||||
try:
|
||||
nativeValueAddress = toInteger(nativeValue.address)
|
||||
except:
|
||||
@@ -565,13 +565,13 @@ class Dumper(DumperBase):
|
||||
#warn(' NATIVE MEMBER ADDRESS: 0x%x' % nativeMemberAddress)
|
||||
offset = nativeMemberAddress - nativeBaseAddress
|
||||
#offset = bpbase + nativeField.bitpos
|
||||
#warn("DEEP OFFSET: %s POS: %s" % (offset // 8, field.lbitpos // 8))
|
||||
#warn('DEEP OFFSET: %s POS: %s' % (offset // 8, field.lbitpos // 8))
|
||||
field.lbitpos = offset * 8
|
||||
except:
|
||||
field.lbitpos = None
|
||||
field.lvalue = "XXX"
|
||||
field.lvalue = 'XXX'
|
||||
#else:
|
||||
# warn("REUSING BITPOS %s FOR %s" % (field.lbitpos, field.name))
|
||||
# warn('REUSING BITPOS %s FOR %s' % (field.lbitpos, field.name))
|
||||
fields.append(field)
|
||||
return fields
|
||||
|
||||
@@ -601,20 +601,20 @@ class Dumper(DumperBase):
|
||||
if symbol.is_variable or symbol.is_argument:
|
||||
name = symbol.print_name
|
||||
|
||||
if name == "__in_chrg" or name == "__PRETTY_FUNCTION__":
|
||||
if name in ('__in_chrg', '__PRETTY_FUNCTION__'):
|
||||
continue
|
||||
|
||||
if not partialVar is None and partialVar != name:
|
||||
continue
|
||||
|
||||
# "NotImplementedError: Symbol type not yet supported in
|
||||
# Python scripts."
|
||||
#warn("SYMBOL %s (%s, %s)): " % (symbol, name, symbol.name))
|
||||
# 'NotImplementedError: Symbol type not yet supported in
|
||||
# Python scripts.'
|
||||
#warn('SYMBOL %s (%s, %s)): ' % (symbol, name, symbol.name))
|
||||
if self.passExceptions and not self.isTesting:
|
||||
nativeValue = frame.read_var(name, block)
|
||||
value = self.fromFrameValue(nativeValue)
|
||||
value.name = name
|
||||
#warn("READ 0: %s" % value.stringify())
|
||||
#warn('READ 0: %s' % value.stringify())
|
||||
items.append(value)
|
||||
continue
|
||||
|
||||
@@ -623,14 +623,14 @@ class Dumper(DumperBase):
|
||||
nativeValue = frame.read_var(name, block)
|
||||
value = self.fromFrameValue(nativeValue)
|
||||
value.name = name
|
||||
#warn('READ 1: %s' % value.stringify())
|
||||
items.append(value)
|
||||
#warn("READ 1: %s" % value.stringify())
|
||||
continue
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
#warn("READ 2: %s" % item.value)
|
||||
#warn('READ 2: %s' % item.value)
|
||||
value = self.fromFrameValue(frame.read_var(name))
|
||||
value.name = name
|
||||
items.append(value)
|
||||
@@ -644,15 +644,15 @@ class Dumper(DumperBase):
|
||||
pass
|
||||
|
||||
try:
|
||||
#warn("READ 3: %s %s" % (name, item.value))
|
||||
#warn("ITEM 3: %s" % item.value)
|
||||
#warn('READ 3: %s %s' % (name, item.value))
|
||||
#warn('ITEM 3: %s' % item.value)
|
||||
value = self.fromFrameValue(gdb.parse_and_eval(name))
|
||||
value.name = name
|
||||
items.append(value)
|
||||
except:
|
||||
# Can happen in inlined code (see last line of
|
||||
# RowPainter::paintChars(): "RuntimeError:
|
||||
# No symbol \"__val\" in current context.\n"
|
||||
# RowPainter::paintChars(): 'RuntimeError:
|
||||
# No symbol '__val' in current context.\n'
|
||||
pass
|
||||
|
||||
# The outermost block in a function has the function member
|
||||
@@ -686,19 +686,19 @@ class Dumper(DumperBase):
|
||||
|
||||
self.output.append('data=[')
|
||||
|
||||
partialVar = args.get("partialvar", "")
|
||||
partialVar = args.get('partialvar', '')
|
||||
isPartial = len(partialVar) > 0
|
||||
partialName = partialVar.split('.')[1].split('@')[0] if isPartial else None
|
||||
|
||||
variables = self.listLocals(partialName)
|
||||
#warn("VARIABLES: %s" % variables)
|
||||
#warn('VARIABLES: %s' % variables)
|
||||
|
||||
# Take care of the return value of the last function call.
|
||||
if len(self.resultVarName) > 0:
|
||||
try:
|
||||
value = self.parseAndEvaluate(self.resultVarName)
|
||||
value.name = self.resultVarName
|
||||
value.iname = "return." + self.resultVarName
|
||||
value.iname = 'return.' + self.resultVarName
|
||||
variables.append(value)
|
||||
except:
|
||||
# Don't bother. It's only supplementary information anyway.
|
||||
@@ -732,7 +732,7 @@ class Dumper(DumperBase):
|
||||
safePrint('"%s"' % str(self.dumpStats()))
|
||||
|
||||
def parseAndEvaluate(self, exp):
|
||||
#warn("EVALUATE '%s'" % exp)
|
||||
#warn('EVALUATE '%s'' % exp)
|
||||
try:
|
||||
val = gdb.parse_and_eval(exp)
|
||||
except RuntimeError as error:
|
||||
@@ -743,7 +743,7 @@ class Dumper(DumperBase):
|
||||
|
||||
def callHelper(self, rettype, value, function, args):
|
||||
# args is a tuple.
|
||||
arg = ""
|
||||
arg = ''
|
||||
for i in range(len(args)):
|
||||
if i:
|
||||
arg += ','
|
||||
@@ -753,41 +753,38 @@ class Dumper(DumperBase):
|
||||
else:
|
||||
arg += a
|
||||
|
||||
#warn("CALL: %s -> %s(%s)" % (value, function, arg))
|
||||
#warn('CALL: %s -> %s(%s)' % (value, function, arg))
|
||||
typeName = value.type.name
|
||||
if typeName.find(":") >= 0:
|
||||
if typeName.find(':') >= 0:
|
||||
typeName = "'" + typeName + "'"
|
||||
# 'class' is needed, see http://sourceware.org/bugzilla/show_bug.cgi?id=11912
|
||||
#exp = "((class %s*)%s)->%s(%s)" % (typeName, value.laddress, function, arg)
|
||||
#exp = '((class %s*)%s)->%s(%s)' % (typeName, value.laddress, function, arg)
|
||||
addr = value.laddress
|
||||
if addr is None:
|
||||
addr = self.pokeValue(value)
|
||||
#warn("PTR: %s -> %s(%s)" % (value, function, addr))
|
||||
exp = "((%s*)0x%x)->%s(%s)" % (typeName, addr, function, arg)
|
||||
#warn('PTR: %s -> %s(%s)' % (value, function, addr))
|
||||
exp = '((%s*)0x%x)->%s(%s)' % (typeName, addr, function, arg)
|
||||
#warn("CALL: %s" % exp)
|
||||
result = gdb.parse_and_eval(exp)
|
||||
warn(" -> %s" % result)
|
||||
#warn(' -> %s' % result)
|
||||
res = self.fromNativeValue(result)
|
||||
if value.laddress is None:
|
||||
self.releaseValue(addr)
|
||||
return res
|
||||
|
||||
def makeExpression(self, value):
|
||||
typename = "::" + value.type.name
|
||||
#warn(" TYPE: %s" % typename)
|
||||
exp = "(*(%s*)(0x%x))" % (typename, value.address())
|
||||
#warn(" EXP: %s" % exp)
|
||||
typename = '::' + value.type.name
|
||||
#warn(' TYPE: %s' % typename)
|
||||
exp = '(*(%s*)(0x%x))' % (typename, value.address())
|
||||
#warn(' EXP: %s' % exp)
|
||||
return exp
|
||||
|
||||
def makeStdString(init):
|
||||
# Works only for small allocators, but they are usually empty.
|
||||
gdb.execute("set $d=(std::string*)calloc(sizeof(std::string), 2)");
|
||||
gdb.execute("call($d->basic_string(\"" + init +
|
||||
"\",*(std::allocator<char>*)(1+$d)))")
|
||||
value = gdb.parse_and_eval("$d").dereference()
|
||||
#warn(" TYPE: %s" % value.type)
|
||||
#warn(" ADDR: %s" % value.address)
|
||||
#warn(" VALUE: %s" % value)
|
||||
gdb.execute('set $d=(std::string*)calloc(sizeof(std::string), 2)');
|
||||
gdb.execute('call($d->basic_string("' + init +
|
||||
'",*(std::allocator<char>*)(1+$d)))')
|
||||
value = gdb.parse_and_eval('$d').dereference()
|
||||
return value
|
||||
|
||||
def pokeValue(self, value):
|
||||
@@ -801,20 +798,20 @@ class Dumper(DumperBase):
|
||||
string = ''.join("\\x" + h[2*i:2*i+2] for i in range(size))
|
||||
exp = '(%s*)memcpy(calloc(%d, 1), "%s", %d)' \
|
||||
% (value.type.name, size, string, size)
|
||||
#warn("EXP: %s" % exp)
|
||||
#warn('EXP: %s' % exp)
|
||||
res = gdb.parse_and_eval(exp)
|
||||
#warn("RES: %s" % res)
|
||||
#warn('RES: %s' % res)
|
||||
return toInteger(res)
|
||||
|
||||
def releaseValue(self, address):
|
||||
gdb.parse_and_eval('free(0x%x)' % address)
|
||||
|
||||
def setValue(self, address, typename, value):
|
||||
cmd = "set {%s}%s=%s" % (typename, address, value)
|
||||
cmd = 'set {%s}%s=%s' % (typename, address, value)
|
||||
gdb.execute(cmd)
|
||||
|
||||
def setValues(self, address, typename, values):
|
||||
cmd = "set {%s[%s]}%s={%s}" \
|
||||
cmd = 'set {%s[%s]}%s={%s}' \
|
||||
% (typename, len(values), address, ','.join(map(str, values)))
|
||||
gdb.execute(cmd)
|
||||
|
||||
@@ -840,7 +837,7 @@ class Dumper(DumperBase):
|
||||
return res
|
||||
|
||||
def findStaticMetaObject(self, typename):
|
||||
symbolName = typename + "::staticMetaObject"
|
||||
symbolName = typename + '::staticMetaObject'
|
||||
symbol = gdb.lookup_global_symbol(symbolName, gdb.SYMBOL_VAR_DOMAIN)
|
||||
if not symbol:
|
||||
return 0
|
||||
@@ -877,7 +874,7 @@ class Dumper(DumperBase):
|
||||
|
||||
def qtVersionString(self):
|
||||
try:
|
||||
return str(gdb.lookup_symbol("qVersion")[0].value()())
|
||||
return str(gdb.lookup_symbol('qVersion')[0].value()())
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
@@ -890,7 +887,7 @@ class Dumper(DumperBase):
|
||||
def qtVersion(self):
|
||||
try:
|
||||
# Only available with Qt 5.3+
|
||||
qtversion = int(str(gdb.parse_and_eval("((void**)&qtHookData)[2]")), 16)
|
||||
qtversion = int(str(gdb.parse_and_eval('((void**)&qtHookData)[2]')), 16)
|
||||
self.qtVersion = lambda: qtversion
|
||||
return qtversion
|
||||
except:
|
||||
@@ -922,24 +919,24 @@ class Dumper(DumperBase):
|
||||
|
||||
# FIXME: ns is accessed too early. gdb.Breakpoint() has no
|
||||
# 'rbreak' replacement, and breakpoints created with
|
||||
# 'gdb.execute("rbreak...") cannot be made invisible.
|
||||
# 'gdb.execute('rbreak...') cannot be made invisible.
|
||||
# So let's ignore the existing of namespaced builds for this
|
||||
# fringe feature here for now.
|
||||
ns = self.qtNamespace()
|
||||
if args.get('breakonabort', 0):
|
||||
self.specialBreakpoints.append(newSpecial("abort"))
|
||||
self.specialBreakpoints.append(newSpecial('abort'))
|
||||
|
||||
if args.get('breakonwarning', 0):
|
||||
self.specialBreakpoints.append(newSpecial(ns + "qWarning"))
|
||||
self.specialBreakpoints.append(newSpecial(ns + "QMessageLogger::warning"))
|
||||
self.specialBreakpoints.append(newSpecial(ns + 'qWarning'))
|
||||
self.specialBreakpoints.append(newSpecial(ns + 'QMessageLogger::warning'))
|
||||
|
||||
if args.get('breakonfatal', 0):
|
||||
self.specialBreakpoints.append(newSpecial(ns + "qFatal"))
|
||||
self.specialBreakpoints.append(newSpecial(ns + "QMessageLogger::fatal"))
|
||||
self.specialBreakpoints.append(newSpecial(ns + 'qFatal'))
|
||||
self.specialBreakpoints.append(newSpecial(ns + 'QMessageLogger::fatal'))
|
||||
|
||||
#def threadname(self, maximalStackDepth, objectPrivateType):
|
||||
# e = gdb.selected_frame()
|
||||
# out = ""
|
||||
# out = ''
|
||||
# ns = self.qtNamespace()
|
||||
# while True:
|
||||
# maximalStackDepth -= 1
|
||||
@@ -948,17 +945,16 @@ class Dumper(DumperBase):
|
||||
# e = e.older()
|
||||
# if e == None or e.name() == None:
|
||||
# break
|
||||
# if e.name() == ns + "QThreadPrivate::start" \
|
||||
# or e.name() == "_ZN14QThreadPrivate5startEPv@4":
|
||||
# if e.name() in (ns + 'QThreadPrivate::start', '_ZN14QThreadPrivate5startEPv@4'):
|
||||
# try:
|
||||
# thrptr = e.read_var("thr").dereference()
|
||||
# d_ptr = thrptr["d_ptr"]["d"].cast(objectPrivateType).dereference()
|
||||
# thrptr = e.read_var('thr').dereference()
|
||||
# d_ptr = thrptr['d_ptr']['d'].cast(objectPrivateType).dereference()
|
||||
# try:
|
||||
# objectName = d_ptr["objectName"]
|
||||
# objectName = d_ptr['objectName']
|
||||
# except: # Qt 5
|
||||
# p = d_ptr["extraData"]
|
||||
# p = d_ptr['extraData']
|
||||
# if not self.isNull(p):
|
||||
# objectName = p.dereference()["objectName"]
|
||||
# objectName = p.dereference()['objectName']
|
||||
# if not objectName is None:
|
||||
# (data, size, alloc) = self.stringData(objectName)
|
||||
# if size > 0:
|
||||
@@ -997,9 +993,9 @@ class Dumper(DumperBase):
|
||||
|
||||
|
||||
def importPlainDumper(self, printer):
|
||||
name = printer.name.replace("::", "__")
|
||||
name = printer.name.replace('::', '__')
|
||||
self.qqDumpers[name] = PlainDumper(printer)
|
||||
self.qqFormats[name] = ""
|
||||
self.qqFormats[name] = ''
|
||||
|
||||
def importPlainDumpers(self):
|
||||
for obj in gdb.objfiles():
|
||||
@@ -1019,7 +1015,7 @@ class Dumper(DumperBase):
|
||||
|
||||
# This only works when called from a valid frame.
|
||||
try:
|
||||
cand = "QArrayData::shared_null"
|
||||
cand = 'QArrayData::shared_null'
|
||||
symbol = gdb.lookup_symbol(cand)[0]
|
||||
if symbol:
|
||||
ns = symbol.name[:-len(cand)]
|
||||
@@ -1031,7 +1027,7 @@ class Dumper(DumperBase):
|
||||
|
||||
try:
|
||||
# This is Qt, but not 5.x.
|
||||
cand = "QByteArray::shared_null"
|
||||
cand = 'QByteArray::shared_null'
|
||||
symbol = gdb.lookup_symbol(cand)[0]
|
||||
if symbol:
|
||||
ns = symbol.name[:-len(cand)]
|
||||
@@ -1053,7 +1049,7 @@ class Dumper(DumperBase):
|
||||
ns = self.qtNamespace()
|
||||
if typeName.startswith(ns):
|
||||
typeName = typeName[len(ns):]
|
||||
typeName = typeName.replace("::", "__")
|
||||
typeName = typeName.replace('::', '__')
|
||||
pos = typeName.find('<')
|
||||
if pos != -1:
|
||||
typeName = typeName[0:pos]
|
||||
@@ -1062,7 +1058,7 @@ class Dumper(DumperBase):
|
||||
expr = gdb.parse_and_eval(expr)
|
||||
self.qqEditable[typeName](self, expr, value)
|
||||
else:
|
||||
cmd = "set variable (%s)=%s" % (expr, value)
|
||||
cmd = 'set variable (%s)=%s' % (expr, value)
|
||||
gdb.execute(cmd)
|
||||
|
||||
def nativeDynamicTypeName(self, address, baseType):
|
||||
@@ -1075,14 +1071,14 @@ class Dumper(DumperBase):
|
||||
val = nativeValue.cast(nativeValue.dynamic_type)
|
||||
return str(val.type)
|
||||
#try:
|
||||
# vtbl = gdb.execute("info symbol {%s*}0x%x" % (baseType.name, address), to_string = True)
|
||||
# vtbl = gdb.execute('info symbol {%s*}0x%x' % (baseType.name, address), to_string = True)
|
||||
#except:
|
||||
# return None
|
||||
#pos1 = vtbl.find("vtable ")
|
||||
#pos1 = vtbl.find('vtable ')
|
||||
#if pos1 == -1:
|
||||
# return None
|
||||
#pos1 += 11
|
||||
#pos2 = vtbl.find(" +", pos1)
|
||||
#pos2 = vtbl.find(' +', pos1)
|
||||
#if pos2 == -1:
|
||||
# return None
|
||||
#return vtbl[pos1 : pos2]
|
||||
@@ -1097,7 +1093,7 @@ class Dumper(DumperBase):
|
||||
return self.fromNativeType(nativeValue.dynamic_type)
|
||||
|
||||
def enumExpression(self, enumType, enumValue):
|
||||
return self.qtNamespace() + "Qt::" + enumValue
|
||||
return self.qtNamespace() + 'Qt::' + enumValue
|
||||
|
||||
def lookupNativeType(self, typeName):
|
||||
nativeType = self.lookupNativeTypeHelper(typeName)
|
||||
@@ -1107,18 +1103,18 @@ class Dumper(DumperBase):
|
||||
|
||||
def lookupNativeTypeHelper(self, typeName):
|
||||
typeobj = self.typeCache.get(typeName)
|
||||
#warn("LOOKUP 1: %s -> %s" % (typeName, typeobj))
|
||||
#warn('LOOKUP 1: %s -> %s' % (typeName, typeobj))
|
||||
if not typeobj is None:
|
||||
return typeobj
|
||||
|
||||
if typeName == "void":
|
||||
if typeName == 'void':
|
||||
typeobj = gdb.lookup_type(typeName)
|
||||
self.typeCache[typeName] = typeobj
|
||||
self.typesToReport[typeName] = typeobj
|
||||
return typeobj
|
||||
|
||||
#try:
|
||||
# typeobj = gdb.parse_and_eval("{%s}&main" % typeName).typeobj
|
||||
# typeobj = gdb.parse_and_eval('{%s}&main' % typeName).typeobj
|
||||
# if not typeobj is None:
|
||||
# self.typeCache[typeName] = typeobj
|
||||
# self.typesToReport[typeName] = typeobj
|
||||
@@ -1127,12 +1123,12 @@ class Dumper(DumperBase):
|
||||
# pass
|
||||
|
||||
# See http://sourceware.org/bugzilla/show_bug.cgi?id=13269
|
||||
# gcc produces "{anonymous}", gdb "(anonymous namespace)"
|
||||
# "<unnamed>" has been seen too. The only thing gdb
|
||||
# understands when reading things back is "(anonymous namespace)"
|
||||
if typeName.find("{anonymous}") != -1:
|
||||
# gcc produces '{anonymous}', gdb '(anonymous namespace)'
|
||||
# '<unnamed>' has been seen too. The only thing gdb
|
||||
# understands when reading things back is '(anonymous namespace)'
|
||||
if typeName.find('{anonymous}') != -1:
|
||||
ts = typeName
|
||||
ts = ts.replace("{anonymous}", "(anonymous namespace)")
|
||||
ts = ts.replace('{anonymous}', '(anonymous namespace)')
|
||||
typeobj = self.lookupNativeType(ts)
|
||||
if not typeobj is None:
|
||||
self.typeCache[typeName] = typeobj
|
||||
@@ -1147,24 +1143,23 @@ class Dumper(DumperBase):
|
||||
|
||||
ts = typeName
|
||||
while True:
|
||||
#warn("TS: '%s'" % ts)
|
||||
if ts.startswith("class "):
|
||||
if ts.startswith('class '):
|
||||
ts = ts[6:]
|
||||
elif ts.startswith("struct "):
|
||||
elif ts.startswith('struct '):
|
||||
ts = ts[7:]
|
||||
elif ts.startswith("const "):
|
||||
elif ts.startswith('const '):
|
||||
ts = ts[6:]
|
||||
elif ts.startswith("volatile "):
|
||||
elif ts.startswith('volatile '):
|
||||
ts = ts[9:]
|
||||
elif ts.startswith("enum "):
|
||||
elif ts.startswith('enum '):
|
||||
ts = ts[5:]
|
||||
elif ts.endswith(" const"):
|
||||
elif ts.endswith(' const'):
|
||||
ts = ts[:-6]
|
||||
elif ts.endswith(" volatile"):
|
||||
elif ts.endswith(' volatile'):
|
||||
ts = ts[:-9]
|
||||
elif ts.endswith("*const"):
|
||||
elif ts.endswith('*const'):
|
||||
ts = ts[:-5]
|
||||
elif ts.endswith("*volatile"):
|
||||
elif ts.endswith('*volatile'):
|
||||
ts = ts[:-8]
|
||||
else:
|
||||
break
|
||||
@@ -1188,19 +1183,19 @@ class Dumper(DumperBase):
|
||||
typeobj = self.parse_and_eval(exp).type.target()
|
||||
#warn("LOOKING UP 3 '%s'" % typeobj)
|
||||
except:
|
||||
# Can throw "RuntimeError: No type named class Foo."
|
||||
# Can throw 'RuntimeError: No type named class Foo.'
|
||||
pass
|
||||
except:
|
||||
#warn("LOOKING UP '%s' FAILED" % ts)
|
||||
pass
|
||||
|
||||
if not typeobj is None:
|
||||
#warn("CACHING: %s" % typeobj)
|
||||
#warn('CACHING: %s' % typeobj)
|
||||
self.typeCache[typeName] = typeobj
|
||||
self.typesToReport[typeName] = typeobj
|
||||
|
||||
# This could still be None as gdb.lookup_type("char[3]") generates
|
||||
# "RuntimeError: No type named char[3]"
|
||||
# This could still be None as gdb.lookup_type('char[3]') generates
|
||||
# 'RuntimeError: No type named char[3]'
|
||||
#self.typeCache[typeName] = typeobj
|
||||
#self.typesToReport[typeName] = typeobj
|
||||
return typeobj
|
||||
@@ -1225,7 +1220,7 @@ class Dumper(DumperBase):
|
||||
frame = gdb.newest_frame()
|
||||
ns = self.qtNamespace()
|
||||
needle = self.qtNamespace() + 'QV4::ExecutionEngine'
|
||||
pat = "%sqt_v4StackTrace(((%sQV4::ExecutionEngine *)0x%x)->currentContext)"
|
||||
pat = '%sqt_v4StackTrace(((%sQV4::ExecutionEngine *)0x%x)->currentContext)'
|
||||
done = False
|
||||
while i < limit and frame and not done:
|
||||
block = None
|
||||
@@ -1260,10 +1255,10 @@ class Dumper(DumperBase):
|
||||
while i < limit and frame:
|
||||
with OutputSafer(self):
|
||||
name = frame.name()
|
||||
functionName = "??" if name is None else name
|
||||
fileName = ""
|
||||
objfile = ""
|
||||
symtab = ""
|
||||
functionName = '??' if name is None else name
|
||||
fileName = ''
|
||||
objfile = ''
|
||||
symtab = ''
|
||||
pc = frame.pc()
|
||||
sal = frame.find_sal()
|
||||
line = -1
|
||||
@@ -1274,13 +1269,13 @@ class Dumper(DumperBase):
|
||||
objfile = fromNativePath(symtab.objfile.filename)
|
||||
fullname = symtab.fullname()
|
||||
if fullname is None:
|
||||
fileName = ""
|
||||
fileName = ''
|
||||
else:
|
||||
fileName = fromNativePath(fullname)
|
||||
|
||||
if self.nativeMixed and functionName == "qt_qmlDebugMessageAvailable":
|
||||
if self.nativeMixed and functionName == 'qt_qmlDebugMessageAvailable':
|
||||
interpreterStack = self.extractInterpreterStack()
|
||||
#print("EXTRACTED INTEPRETER STACK: %s" % interpreterStack)
|
||||
#print('EXTRACTED INTEPRETER STACK: %s' % interpreterStack)
|
||||
for interpreterFrame in interpreterStack.get('frames', []):
|
||||
function = interpreterFrame.get('function', '')
|
||||
fileName = interpreterFrame.get('file', '')
|
||||
@@ -1315,7 +1310,7 @@ class Dumper(DumperBase):
|
||||
def __init__(self, dumper, args):
|
||||
self.dumper = dumper
|
||||
self.args = args
|
||||
spec = "qt_qmlDebugConnectorOpen"
|
||||
spec = 'qt_qmlDebugConnectorOpen'
|
||||
super(Resolver, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True, temporary=False)
|
||||
|
||||
@@ -1327,16 +1322,16 @@ class Dumper(DumperBase):
|
||||
self.interpreterBreakpointResolvers.append(Resolver(self, args))
|
||||
|
||||
def exitGdb(self, _):
|
||||
gdb.execute("quit")
|
||||
gdb.execute('quit')
|
||||
|
||||
def reportResult(self, msg, args):
|
||||
print(msg)
|
||||
|
||||
def profile1(self, args):
|
||||
"""Internal profiling"""
|
||||
'''Internal profiling'''
|
||||
import tempfile
|
||||
import cProfile
|
||||
tempDir = tempfile.gettempdir() + "/bbprof"
|
||||
tempDir = tempfile.gettempdir() + '/bbprof'
|
||||
cProfile.run('theDumper.fetchVariables(%s)' % args, tempDir)
|
||||
import pstats
|
||||
pstats.Stats(tempDir).sort_stats('time').print_stats()
|
||||
@@ -1398,7 +1393,7 @@ theDumper = Dumper()
|
||||
def threadnames(arg):
|
||||
return theDumper.threadnames(int(arg))
|
||||
|
||||
registerCommand("threadnames", threadnames)
|
||||
registerCommand('threadnames', threadnames)
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
@@ -1408,12 +1403,12 @@ registerCommand("threadnames", threadnames)
|
||||
|
||||
class InterpreterMessageBreakpoint(gdb.Breakpoint):
|
||||
def __init__(self):
|
||||
spec = "qt_qmlDebugMessageAvailable"
|
||||
spec = 'qt_qmlDebugMessageAvailable'
|
||||
super(InterpreterMessageBreakpoint, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True)
|
||||
|
||||
def stop(self):
|
||||
print("Interpreter event received.")
|
||||
print('Interpreter event received.')
|
||||
return theDumper.handleInterpreterMessage()
|
||||
|
||||
#InterpreterMessageBreakpoint()
|
||||
|
@@ -231,18 +231,18 @@ class Dumper:
|
||||
# Hex decoding operating on str, return str.
|
||||
def hexdecode(self, s):
|
||||
if sys.version_info[0] == 2:
|
||||
return s.decode("hex")
|
||||
return bytes.fromhex(s).decode("utf8")
|
||||
return s.decode('hex')
|
||||
return bytes.fromhex(s).decode('utf8')
|
||||
|
||||
# Hex encoding operating on str or bytes, return str.
|
||||
def hexencode(self, s):
|
||||
if sys.version_info[0] == 2:
|
||||
return s.encode("hex")
|
||||
return s.encode('hex')
|
||||
if isinstance(s, str):
|
||||
s = s.encode("utf8")
|
||||
return base64.b16encode(s).decode("utf8")
|
||||
s = s.encode('utf8')
|
||||
return base64.b16encode(s).decode('utf8')
|
||||
def canonic(self, filename):
|
||||
if filename == "<" + filename[1:-1] + ">":
|
||||
if filename == '<' + filename[1:-1] + '>':
|
||||
return filename
|
||||
canonic = self.fncache.get(filename)
|
||||
if not canonic:
|
||||
@@ -572,7 +572,7 @@ class Dumper:
|
||||
locals = globals
|
||||
self.reset()
|
||||
if isinstance(cmd, str):
|
||||
cmd = compile(cmd, "<string>", "exec")
|
||||
cmd = compile(cmd, '<string>', 'exec')
|
||||
sys.settrace(self.trace_dispatch)
|
||||
try:
|
||||
exec(cmd, globals, locals)
|
||||
@@ -641,7 +641,7 @@ class Dumper:
|
||||
line = 'EOF'
|
||||
else:
|
||||
line = line.rstrip('\r\n')
|
||||
print("LINE: %s" % line)
|
||||
print('LINE: %s' % line)
|
||||
stop = self.onecmd(line)
|
||||
finally:
|
||||
pass
|
||||
@@ -674,9 +674,9 @@ class Dumper:
|
||||
commands by the interpreter should stop.
|
||||
"""
|
||||
line = str(line)
|
||||
print("LINE 0: %s" % line)
|
||||
print('LINE 0: %s' % line)
|
||||
cmd, arg, line = self.parseline(line)
|
||||
print("LINE 1: %s" % line)
|
||||
print('LINE 1: %s' % line)
|
||||
if cmd is None:
|
||||
return self.default(line)
|
||||
self.lastcmd = line
|
||||
@@ -693,15 +693,15 @@ class Dumper:
|
||||
|
||||
def runit(self):
|
||||
|
||||
print("DIR: %s" % dir())
|
||||
print('DIR: %s' % dir())
|
||||
if sys.argv[0] == '-c':
|
||||
sys.argv = sys.argv[2:]
|
||||
else:
|
||||
sys.argv = sys.argv[1:]
|
||||
print("ARGV: %s" % sys.argv)
|
||||
print('ARGV: %s' % sys.argv)
|
||||
mainpyfile = sys.argv[0] # Get script filename
|
||||
sys.path.append(os.path.dirname(mainpyfile))
|
||||
print("MAIN: %s" % mainpyfile)
|
||||
print('MAIN: %s' % mainpyfile)
|
||||
|
||||
while True:
|
||||
try:
|
||||
@@ -713,9 +713,9 @@ class Dumper:
|
||||
|
||||
#import __main__
|
||||
#__main__.__dict__.clear()
|
||||
#__main__.__dict__.update({"__name__" : "__main__",
|
||||
# "__file__" : mainpyfile,
|
||||
# "__builtins__": __builtins__,
|
||||
#__main__.__dict__.update({'__name__' : '__main__',
|
||||
# '__file__' : mainpyfile,
|
||||
# '__builtins__': __builtins__,
|
||||
# })
|
||||
|
||||
# When bdb sets tracing, a number of call and line events happens
|
||||
@@ -726,26 +726,26 @@ class Dumper:
|
||||
self._wait_for_mainpyfile = True
|
||||
self.mainpyfile = self.canonic(mainpyfile)
|
||||
self._user_requested_quit = False
|
||||
with open(mainpyfile, "rb") as fp:
|
||||
with open(mainpyfile, 'rb') as fp:
|
||||
statement = "exec(compile(%r, %r, 'exec'))" % \
|
||||
(fp.read(), self.mainpyfile)
|
||||
self.run(statement)
|
||||
|
||||
if self._user_requested_quit:
|
||||
break
|
||||
print("The program finished")
|
||||
print('The program finished')
|
||||
except SystemExit:
|
||||
# In most cases SystemExit does not warrant a post-mortem session.
|
||||
print("The program exited via sys.exit(). Exit status:")
|
||||
print('The program exited via sys.exit(). Exit status:')
|
||||
print(sys.exc_info()[1])
|
||||
except:
|
||||
traceback.print_exc()
|
||||
print("Uncaught exception. Entering post mortem debugging")
|
||||
print("Running 'cont' or 'step' will restart the program")
|
||||
print('Uncaught exception. Entering post mortem debugging')
|
||||
print('Running "cont" or "step" will restart the program')
|
||||
t = sys.exc_info()[2]
|
||||
self.interaction(None, t)
|
||||
print("Post mortem debugger finished. The " + mainpyfile +
|
||||
" will be restarted")
|
||||
print('Post mortem debugger finished. The ' + mainpyfile +
|
||||
' will be restarted')
|
||||
|
||||
def sigint_handler(self, signum, frame):
|
||||
if self.allow_kbdint:
|
||||
@@ -839,7 +839,7 @@ class Dumper:
|
||||
def interaction(self, frame, traceback):
|
||||
if self.setup(frame, traceback):
|
||||
# no interaction desired at this time (happens if .pdbrc contains
|
||||
# a command like "continue")
|
||||
# a command like 'continue')
|
||||
self.forget()
|
||||
return
|
||||
|
||||
@@ -926,7 +926,7 @@ class Dumper:
|
||||
cond = None
|
||||
comma = arg.find(',')
|
||||
if comma > 0:
|
||||
# parse stuff after comma: "condition"
|
||||
# parse stuff after comma: 'condition'
|
||||
cond = arg[comma+1:].lstrip()
|
||||
arg = arg[:comma].rstrip()
|
||||
# parse stuff before comma: [filename:]lineno | function
|
||||
@@ -986,7 +986,7 @@ class Dumper:
|
||||
self.error(err)
|
||||
else:
|
||||
bp = self.get_breaks(filename, line)[-1]
|
||||
self.message("Breakpoint %d at %s:%d" %
|
||||
self.message('Breakpoint %d at %s:%d' %
|
||||
(bp.number, bp.file, bp.line))
|
||||
|
||||
# To be overridden in derived debuggers
|
||||
@@ -1169,14 +1169,14 @@ class Dumper:
|
||||
self.message('Deleted %s' % bp)
|
||||
return
|
||||
if ':' in arg:
|
||||
# Make sure it works for "clear C:\foo\bar.py:12"
|
||||
# Make sure it works for 'clear C:\foo\bar.py:12'
|
||||
i = arg.rfind(':')
|
||||
filename = arg[:i]
|
||||
arg = arg[i+1:]
|
||||
try:
|
||||
lineno = int(arg)
|
||||
except ValueError:
|
||||
err = "Invalid line number (%s)" % arg
|
||||
err = 'Invalid line number (%s)' % arg
|
||||
else:
|
||||
bplist = self.get_breaks(filename, lineno)
|
||||
err = self.clear_break(filename, lineno)
|
||||
@@ -1290,9 +1290,9 @@ class Dumper:
|
||||
globals = self.curframe.f_globals
|
||||
locals = self.curframe_locals
|
||||
p = Dumper(self.stdin, self.stdout)
|
||||
self.message("ENTERING RECURSIVE DEBUGGER")
|
||||
self.message('ENTERING RECURSIVE DEBUGGER')
|
||||
sys.call_tracing(p.run, (arg, globals, locals))
|
||||
self.message("LEAVING RECURSIVE DEBUGGER")
|
||||
self.message('LEAVING RECURSIVE DEBUGGER')
|
||||
sys.settrace(self.trace_dispatch)
|
||||
self.lastcmd = p.lastcmd
|
||||
|
||||
@@ -1398,7 +1398,7 @@ class Dumper:
|
||||
"""
|
||||
ns = self.curframe.f_globals.copy()
|
||||
ns.update(self.curframe_locals)
|
||||
code.interact("*interactive*", local=ns)
|
||||
code.interact('*interactive*', local=ns)
|
||||
|
||||
def lookupmodule(self, filename):
|
||||
"""Helper function for break/clear parsing -- may be overridden.
|
||||
@@ -1428,12 +1428,12 @@ class Dumper:
|
||||
self.updateData(args)
|
||||
|
||||
def updateData(self, args):
|
||||
self.expandedINames = set(args.get("expanded", []))
|
||||
self.typeformats = args.get("typeformats", {})
|
||||
self.formats = args.get("formats", {})
|
||||
self.output = ""
|
||||
self.expandedINames = set(args.get('expanded', []))
|
||||
self.typeformats = args.get('typeformats', {})
|
||||
self.formats = args.get('formats', {})
|
||||
self.output = ''
|
||||
|
||||
frameNr = args.get("frame", 0)
|
||||
frameNr = args.get('frame', 0)
|
||||
if frameNr == -1:
|
||||
frameNr = 0
|
||||
|
||||
@@ -1441,33 +1441,33 @@ class Dumper:
|
||||
frame, lineno = frame_lineno
|
||||
filename = self.canonic(frame.f_code.co_filename)
|
||||
|
||||
self.output += "data={"
|
||||
self.output += 'data={'
|
||||
for var in frame.f_locals.keys():
|
||||
if var in ("__file__", "__name__", "__package__", "__spec__",
|
||||
"__doc__", "__loader__", "__cached__", "__the_dumper__"):
|
||||
if var in ('__file__', '__name__', '__package__', '__spec__',
|
||||
'__doc__', '__loader__', '__cached__', '__the_dumper__'):
|
||||
continue
|
||||
value = frame.f_locals[var]
|
||||
# this applies only for anonymous arguments
|
||||
# e.g. def dummy(var, (width, height), var2) would create an anonymous local var
|
||||
# named '.1' for (width, height) as this is the second argument
|
||||
if var.startswith('.'):
|
||||
var = "@arg" + var[1:]
|
||||
self.dumpValue(value, var, "local.%s" % var)
|
||||
var = '@arg' + var[1:]
|
||||
self.dumpValue(value, var, 'local.%s' % var)
|
||||
|
||||
for watcher in args.get("watchers", []):
|
||||
for watcher in args.get('watchers', []):
|
||||
iname = watcher['iname']
|
||||
exp = self.hexdecode(watcher['exp'])
|
||||
exp = str(exp).strip()
|
||||
escapedExp = self.hexencode(exp)
|
||||
self.put("{")
|
||||
self.putField("iname", iname)
|
||||
self.putField("wname", escapedExp)
|
||||
self.put('{')
|
||||
self.putField('iname', iname)
|
||||
self.putField('wname', escapedExp)
|
||||
try:
|
||||
res = eval(exp, {}, frame.f_locals)
|
||||
self.putValue(res)
|
||||
except:
|
||||
self.putValue("<unavailable>")
|
||||
self.put("}")
|
||||
self.putValue('<unavailable>')
|
||||
self.put('}')
|
||||
#self.dumpValue(eval(value), escapedExp, iname)
|
||||
|
||||
self.output += '}'
|
||||
@@ -1475,9 +1475,9 @@ class Dumper:
|
||||
self.flushOutput()
|
||||
|
||||
def flushOutput(self):
|
||||
sys.stdout.write("@\n" + self.output + "@\n")
|
||||
sys.stdout.write('@\n' + self.output + '@\n')
|
||||
sys.stdout.flush()
|
||||
self.output = ""
|
||||
self.output = ''
|
||||
|
||||
def put(self, value):
|
||||
#sys.stdout.write(value)
|
||||
@@ -1498,22 +1498,22 @@ class Dumper:
|
||||
return t
|
||||
|
||||
def putType(self, type, priority = 0):
|
||||
self.putField("type", self.cleanType(type))
|
||||
self.putField('type', self.cleanType(type))
|
||||
|
||||
def putNumChild(self, numchild):
|
||||
self.put('numchild="%s",' % numchild)
|
||||
|
||||
def putValue(self, value, encoding = None, priority = 0):
|
||||
self.putField("value", value)
|
||||
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"):
|
||||
#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))
|
||||
#self.warn(' --> %s' % (iname in self.expandedINames))
|
||||
return iname in self.expandedINames
|
||||
|
||||
def isExpandedIName(self, iname):
|
||||
@@ -1528,138 +1528,134 @@ class Dumper:
|
||||
# Hex encoding operating on str or bytes, return str.
|
||||
def hexencode(self, s):
|
||||
if sys.version_info[0] == 2:
|
||||
return s.encode("hex")
|
||||
return s.encode('hex')
|
||||
if isinstance(s, str):
|
||||
s = s.encode("utf8")
|
||||
return base64.b16encode(s).decode("utf8")
|
||||
s = s.encode('utf8')
|
||||
return base64.b16encode(s).decode('utf8')
|
||||
|
||||
def dumpValue(self, value, name, iname):
|
||||
t = type(value)
|
||||
tt = self.cleanType(t)
|
||||
if tt == "module" or tt == "function":
|
||||
if tt == 'module' or tt == 'function':
|
||||
return
|
||||
if str(value).startswith("<class '"):
|
||||
return
|
||||
# FIXME: Should we?
|
||||
if str(value).startswith("<enum-item "):
|
||||
if str(value).startswith('<enum-item '):
|
||||
return
|
||||
self.put("{")
|
||||
self.putField("iname", iname)
|
||||
self.put('{')
|
||||
self.putField('iname', iname)
|
||||
self.putName(name)
|
||||
if tt == "NoneType":
|
||||
if tt == 'NoneType':
|
||||
self.putType(tt)
|
||||
self.putValue("None")
|
||||
self.putValue('None')
|
||||
self.putNumChild(0)
|
||||
elif tt == "list" or tt == "tuple":
|
||||
elif tt == 'list' or tt == 'tuple':
|
||||
self.putType(tt)
|
||||
self.putItemCount(len(value))
|
||||
#self.putValue(value)
|
||||
self.put("children=[")
|
||||
self.put('children=[')
|
||||
for i in range(len(value)):
|
||||
self.dumpValue(value[i], str(i), "%s.%d" % (iname, i))
|
||||
self.put("]")
|
||||
elif tt == "str":
|
||||
self.dumpValue(value[i], str(i), '%s.%d' % (iname, i))
|
||||
self.put(']')
|
||||
elif tt == 'str':
|
||||
v = value
|
||||
self.putType(tt)
|
||||
self.putValue(self.hexencode(v))
|
||||
self.putField("valueencoded", "utf8")
|
||||
self.putField('valueencoded', 'utf8')
|
||||
self.putNumChild(0)
|
||||
elif tt == "unicode":
|
||||
elif tt == 'unicode':
|
||||
v = value
|
||||
self.putType(tt)
|
||||
self.putValue(self.hexencode(v))
|
||||
self.putField("valueencoded", "utf8")
|
||||
self.putField('valueencoded', 'utf8')
|
||||
self.putNumChild(0)
|
||||
elif tt == "buffer":
|
||||
elif tt == 'buffer':
|
||||
v = str(value)
|
||||
self.putType(tt)
|
||||
self.putValue(self.hexencode(v))
|
||||
self.putField("valueencoded", "latin1")
|
||||
self.putField('valueencoded', 'latin1')
|
||||
self.putNumChild(0)
|
||||
elif tt == "xrange":
|
||||
elif tt == 'xrange':
|
||||
b = iter(value).next()
|
||||
e = b + len(value)
|
||||
self.putType(tt)
|
||||
self.putValue("(%d, %d)" % (b, e))
|
||||
self.putValue('(%d, %d)' % (b, e))
|
||||
self.putNumChild(0)
|
||||
elif tt == "dict":
|
||||
elif tt == 'dict':
|
||||
self.putType(tt)
|
||||
self.putItemCount(len(value))
|
||||
self.putField("childnumchild", 2)
|
||||
self.put("children=[")
|
||||
self.putField('childnumchild', 2)
|
||||
self.put('children=[')
|
||||
i = 0
|
||||
if sys.version_info[0] >= 3:
|
||||
vals = value.items()
|
||||
else:
|
||||
vals = value.iteritems()
|
||||
for (k, v) in vals:
|
||||
self.put("{")
|
||||
self.putType(" ")
|
||||
self.putValue("%s: %s" % (k, v))
|
||||
self.put('{')
|
||||
self.putType(' ')
|
||||
self.putValue('%s: %s' % (k, v))
|
||||
if self.isExpanded(iname):
|
||||
self.put("children=[")
|
||||
self.dumpValue(k, "key", "%s.%d.k" % (iname, i))
|
||||
self.dumpValue(v, "value", "%s.%d.v" % (iname, i))
|
||||
self.put("]")
|
||||
self.put("},")
|
||||
self.put('children=[')
|
||||
self.dumpValue(k, 'key', '%s.%d.k' % (iname, i))
|
||||
self.dumpValue(v, 'value', '%s.%d.v' % (iname, i))
|
||||
self.put(']')
|
||||
self.put('},')
|
||||
i += 1
|
||||
self.put("]")
|
||||
elif tt == "class":
|
||||
self.put(']')
|
||||
elif tt == 'class':
|
||||
pass
|
||||
elif tt == "module":
|
||||
elif tt == 'module':
|
||||
pass
|
||||
elif tt == "function":
|
||||
elif tt == 'function':
|
||||
pass
|
||||
elif str(value).startswith("<enum-item "):
|
||||
elif str(value).startswith('<enum-item '):
|
||||
# FIXME: Having enums always shown like this is not nice.
|
||||
self.putType(tt)
|
||||
self.putValue(str(value)[11:-1])
|
||||
self.putNumChild(0)
|
||||
else:
|
||||
v = str(value)
|
||||
p = v.find(" object at ")
|
||||
p = v.find(' object at ')
|
||||
if p > 1:
|
||||
self.putValue("@" + v[p + 11:-1])
|
||||
self.putValue('@' + v[p + 11:-1])
|
||||
self.putType(v[1:p])
|
||||
else:
|
||||
p = v.find(" instance at ")
|
||||
p = v.find(' instance at ')
|
||||
if p > 1:
|
||||
self.putValue("@" + v[p + 13:-1])
|
||||
self.putValue('@' + v[p + 13:-1])
|
||||
self.putType(v[1:p])
|
||||
else:
|
||||
self.putType(tt)
|
||||
self.putValue(v)
|
||||
if self.isExpanded(iname):
|
||||
self.put("children=[")
|
||||
self.put('children=[')
|
||||
for child in dir(value):
|
||||
if child == "__dict__":
|
||||
continue
|
||||
if child == "__doc__":
|
||||
continue
|
||||
if child == "__module__":
|
||||
if child in ('__dict__', '__doc__', '__module__'):
|
||||
continue
|
||||
attr = getattr(value, child)
|
||||
if callable(attr):
|
||||
continue
|
||||
try:
|
||||
self.dumpValue(attr, child, "%s.%s" % (iname, child))
|
||||
self.dumpValue(attr, child, '%s.%s' % (iname, child))
|
||||
except:
|
||||
pass
|
||||
self.put("],")
|
||||
self.put("},")
|
||||
self.put('],')
|
||||
self.put('},')
|
||||
|
||||
|
||||
def warn(self, msg):
|
||||
self.putField("warning", msg)
|
||||
self.putField('warning', msg)
|
||||
|
||||
def listModules(self, args):
|
||||
self.put("modules=[");
|
||||
self.put('modules=[');
|
||||
for name in sys.modules:
|
||||
self.put("{")
|
||||
self.put('{')
|
||||
self.putName(name)
|
||||
self.putValue(sys.modules[name])
|
||||
self.put("},")
|
||||
self.put("]")
|
||||
self.put('},')
|
||||
self.put(']')
|
||||
self.flushOutput()
|
||||
|
||||
def listSymbols(self, args):
|
||||
@@ -1672,9 +1668,9 @@ class Dumper:
|
||||
def assignValue(self, args):
|
||||
exp = args['expression']
|
||||
value = args['value']
|
||||
cmd = "%s=%s" % (exp, exp, value)
|
||||
cmd = '%s=%s' % (exp, exp, value)
|
||||
eval(cmd, {})
|
||||
self.put("CMD: '%s'" % cmd)
|
||||
self.put('CMD: '%s'' % cmd)
|
||||
self.flushOutput()
|
||||
|
||||
def stackListFrames(self, args):
|
||||
@@ -1705,7 +1701,7 @@ class Dumper:
|
||||
self.report(result)
|
||||
|
||||
def report(self, stuff):
|
||||
sys.stdout.write("@\n" + stuff + "@\n")
|
||||
sys.stdout.write('@\n' + stuff + '@\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user