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