forked from qt-creator/qt-creator
Debugger: Streamline encoding handling
Replace base64 with hex encoding, centralize conversions, drop dependency on binascii module. Task-number: QTCREATORBUG-11317 Change-Id: Id3d419d4fe8f75710352f4bc0e6310be849426bd Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -56,31 +56,29 @@ except:
|
||||
return "Normal"
|
||||
|
||||
|
||||
def bytesToString(b):
|
||||
if sys.version_info[0] == 2:
|
||||
return b
|
||||
return b.decode("utf8")
|
||||
class Blob(object):
|
||||
"""
|
||||
Helper structure to keep a blob of bytes, possibly
|
||||
in the inferior.
|
||||
"""
|
||||
|
||||
def stringToBytes(s):
|
||||
if sys.version_info[0] == 2:
|
||||
return s
|
||||
return s.encode("utf8")
|
||||
def __init__(self, data, isComplete = True):
|
||||
self.data = data
|
||||
self.size = len(data)
|
||||
self.isComplete = isComplete
|
||||
|
||||
# Base 16 decoding operating on string->string
|
||||
def b16decode(s):
|
||||
return bytesToString(base64.b16decode(stringToBytes(s), True))
|
||||
def size(self):
|
||||
return self.size
|
||||
|
||||
# Base 16 decoding operating on string->string
|
||||
def b16encode(s):
|
||||
return bytesToString(base64.b16encode(stringToBytes(s)))
|
||||
def toHexOutput(self):
|
||||
if hasattr(self.data, "tobytes"):
|
||||
encoded = base64.b16encode(self.data.tobytes())
|
||||
else:
|
||||
encoded = base64.b16encode(self.data)
|
||||
|
||||
# Base 64 decoding operating on string->string
|
||||
def b64decode(s):
|
||||
return bytesToString(base64.b64decode(stringToBytes(s)))
|
||||
|
||||
# Base 64 decoding operating on string->string
|
||||
def b64encode(s):
|
||||
return bytesToString(base64.b64encode(stringToBytes(s)))
|
||||
if hasattr(encoded, "decode"):
|
||||
return encoded.decode("utf8")
|
||||
return encoded
|
||||
|
||||
|
||||
#
|
||||
@@ -298,6 +296,18 @@ class DumperBase:
|
||||
self.cachedFormats[typeName] = stripped
|
||||
return stripped
|
||||
|
||||
# Hex decoding operating on string->string
|
||||
def hexdecode(self, s):
|
||||
if sys.version_info[0] == 2:
|
||||
return s.decode("hex")
|
||||
return bytes.fromhex(s).decode("utf8")
|
||||
|
||||
# Hex decoding operating on string->string
|
||||
def hexencode(self, s):
|
||||
if sys.version_info[0] == 2:
|
||||
return s.encode("hex")
|
||||
return base64.b16encode(s.encode("utf8")).decode("utf8")
|
||||
|
||||
def isArmArchitecture(self):
|
||||
return False
|
||||
|
||||
@@ -368,6 +378,9 @@ class DumperBase:
|
||||
s += "2e2e2e"
|
||||
return s
|
||||
|
||||
def readMemory(self, addr, size):
|
||||
return self.extractBlob(addr, size).toHexOutput()
|
||||
|
||||
def encodeByteArray(self, value):
|
||||
return self.encodeByteArrayHelper(self.dereferenceValue(value))
|
||||
|
||||
@@ -692,7 +705,7 @@ class DumperBase:
|
||||
if format == 0:
|
||||
# Explicitly requested bald pointer.
|
||||
self.putType(typeName)
|
||||
self.putValue(b16encode(str(value)), Hex2EncodedUtf8WithoutQuotes)
|
||||
self.putValue(self.hexencode(str(value)), Hex2EncodedUtf8WithoutQuotes)
|
||||
self.putNumChild(1)
|
||||
if self.currentIName in self.expandedINames:
|
||||
with Children(self):
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
import binascii
|
||||
try:
|
||||
import __builtin__
|
||||
except:
|
||||
@@ -498,7 +497,7 @@ class Dumper(DumperBase):
|
||||
for f in arg[pos:].split(","):
|
||||
pos = f.find("=")
|
||||
if pos != -1:
|
||||
type = b16decode(f[0:pos])
|
||||
type = self.hexdecode(f[0:pos])
|
||||
self.typeformats[type] = int(f[pos+1:])
|
||||
elif arg.startswith("formats:"):
|
||||
for f in arg[pos:].split(","):
|
||||
@@ -506,7 +505,7 @@ class Dumper(DumperBase):
|
||||
if pos != -1:
|
||||
self.formats[f[0:pos]] = int(f[pos+1:])
|
||||
elif arg.startswith("watchers:"):
|
||||
watchers = b16decode(arg[pos:])
|
||||
watchers = self.hexdecode(arg[pos:])
|
||||
|
||||
self.useDynamicType = "dyntype" in options
|
||||
self.useFancy = "fancy" in options
|
||||
@@ -621,7 +620,7 @@ class Dumper(DumperBase):
|
||||
# Happens e.g. for '(anonymous namespace)::InsertDefOperation'
|
||||
if not type is None:
|
||||
self.output.append('{name="%s",size="%s"}'
|
||||
% (b64encode(name), type.sizeof))
|
||||
% (self.hexencode(name), type.sizeof))
|
||||
self.output.append(']')
|
||||
self.typesToReport = {}
|
||||
return "".join(self.output)
|
||||
@@ -818,7 +817,7 @@ class Dumper(DumperBase):
|
||||
|
||||
def handleWatch(self, exp, iname):
|
||||
exp = str(exp)
|
||||
escapedExp = b64encode(exp);
|
||||
escapedExp = self.hexencode(exp);
|
||||
#warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname))
|
||||
if exp.startswith("[") and exp.endswith("]"):
|
||||
#warn("EVAL: EXP: %s" % exp)
|
||||
@@ -1430,12 +1429,9 @@ class Dumper(DumperBase):
|
||||
with Children(self):
|
||||
self.putFields(value)
|
||||
|
||||
def readMemory(self, base, size):
|
||||
def extractBlob(self, base, size):
|
||||
inferior = self.selectedInferior()
|
||||
mem = inferior.read_memory(base, size)
|
||||
if sys.version_info[0] >= 3:
|
||||
return bytesToString(binascii.hexlify(mem.tobytes()))
|
||||
return binascii.hexlify(mem)
|
||||
return Blob(inferior.read_memory(base, size))
|
||||
|
||||
def readCArray(self, base, size):
|
||||
inferior = self.selectedInferior()
|
||||
@@ -1468,9 +1464,6 @@ class Dumper(DumperBase):
|
||||
#if sys.version_info[0] >= 3:
|
||||
# return mem.tobytes()
|
||||
return mem
|
||||
#if sys.version_info[0] >= 3:
|
||||
# return bytesToString(binascii.hexlify(mem.tobytes()))
|
||||
#return binascii.hexlify(mem)
|
||||
|
||||
def putFields(self, value, dumpBase = True):
|
||||
fields = value.type.fields()
|
||||
@@ -1705,7 +1698,8 @@ class Dumper(DumperBase):
|
||||
|
||||
def bbedit(self, args):
|
||||
(typeName, expr, data) = args.split(',')
|
||||
typeName = b16decode(typeName)
|
||||
d = Dumper()
|
||||
typeName = d.hexdecode(typeName)
|
||||
ns = self.qtNamespace()
|
||||
if typeName.startswith(ns):
|
||||
typeName = typeName[len(ns):]
|
||||
@@ -1713,8 +1707,8 @@ class Dumper(DumperBase):
|
||||
pos = typeName.find('<')
|
||||
if pos != -1:
|
||||
typeName = typeName[0:pos]
|
||||
expr = b16decode(expr)
|
||||
data = b16decode(data)
|
||||
expr = d.hexdecode(expr)
|
||||
data = d.hexdecode(data)
|
||||
if typeName in self.qqEditable:
|
||||
#self.qqEditable[typeName](self, expr, data)
|
||||
value = gdb.parse_and_eval(expr)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#############################################################################
|
||||
|
||||
import atexit
|
||||
import binascii
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
@@ -850,14 +849,13 @@ class Dumper(DumperBase):
|
||||
self.currentTypePriority = self.currentTypePriority + 1
|
||||
#warn("BETTER TYPE: %s PRIORITY: %s" % (type, self.currentTypePriority))
|
||||
|
||||
def readMemory(self, base, size):
|
||||
def extractBlob(self, base, size):
|
||||
if size == 0:
|
||||
return ""
|
||||
return Blob("")
|
||||
base = int(base) & 0xFFFFFFFFFFFFFFFF
|
||||
size = int(size) & 0xFFFFFFFF
|
||||
error = lldb.SBError()
|
||||
contents = self.process.ReadMemory(base, size, error)
|
||||
return binascii.hexlify(contents)
|
||||
return Blob(self.process.ReadMemory(base, size, error))
|
||||
|
||||
def isQObject(self, value):
|
||||
try:
|
||||
@@ -1092,7 +1090,7 @@ class Dumper(DumperBase):
|
||||
iname = watcher['iname']
|
||||
# could be 'watch.0' or 'tooltip.deadbead'
|
||||
(base, component) = iname.split('.')
|
||||
exp = binascii.unhexlify(watcher['exp'])
|
||||
exp = self.hexdecode(watcher['exp'])
|
||||
if exp == "":
|
||||
self.put('type="",value="",exp=""')
|
||||
continue
|
||||
@@ -1103,7 +1101,7 @@ class Dumper(DumperBase):
|
||||
self.currentIName = base
|
||||
with SubItem(self, component):
|
||||
self.put('exp="%s",' % exp)
|
||||
self.put('wname="%s",' % binascii.hexlify(exp))
|
||||
self.put('wname="%s",' % self.hexencode(exp))
|
||||
self.put('iname="%s",' % iname)
|
||||
self.putItem(value)
|
||||
|
||||
@@ -1212,11 +1210,11 @@ class Dumper(DumperBase):
|
||||
# FIXME: Size?
|
||||
msg = self.process.GetSTDOUT(1024)
|
||||
self.report('output={channel="stdout",data="%s"}'
|
||||
% binascii.hexlify(msg))
|
||||
% self.hexencode(msg))
|
||||
elif type == lldb.SBProcess.eBroadcastBitSTDERR:
|
||||
msg = self.process.GetSTDERR(1024)
|
||||
self.report('output={channel="stderr",data="%s"}'
|
||||
% binascii.hexlify(msg))
|
||||
% self.hexencode(msg))
|
||||
elif type == lldb.SBProcess.eBroadcastBitProfileData:
|
||||
pass
|
||||
|
||||
@@ -1236,7 +1234,7 @@ class Dumper(DumperBase):
|
||||
result += ',oneshot="%s"' % (1 if bp.IsOneShot() else 0)
|
||||
if hasattr(bp, 'GetCondition'):
|
||||
cond = bp.GetCondition()
|
||||
result += ',condition="%s"' % binascii.hexlify("" if cond is None else cond)
|
||||
result += ',condition="%s"' % self.hexencode("" if cond is None else cond)
|
||||
result += ',enabled="%s"' % (1 if bp.IsEnabled() else 0)
|
||||
result += ',valid="%s"' % (1 if bp.IsValid() else 0)
|
||||
result += ',ignorecount="%s"' % bp.GetIgnoreCount()
|
||||
@@ -1293,7 +1291,7 @@ class Dumper(DumperBase):
|
||||
return
|
||||
bpNew.SetIgnoreCount(int(args["ignorecount"]))
|
||||
if hasattr(bpNew, 'SetCondition'):
|
||||
bpNew.SetCondition(binascii.unhexlify(args["condition"]))
|
||||
bpNew.SetCondition(self.hexdecode(args["condition"]))
|
||||
bpNew.SetEnabled(int(args["enabled"]))
|
||||
if hasattr(bpNew, 'SetOneShot'):
|
||||
bpNew.SetOneShot(int(args["oneshot"]))
|
||||
@@ -1306,7 +1304,7 @@ class Dumper(DumperBase):
|
||||
else:
|
||||
bp = self.target.FindBreakpointByID(id)
|
||||
bp.SetIgnoreCount(int(args["ignorecount"]))
|
||||
bp.SetCondition(binascii.unhexlify(args["condition"]))
|
||||
bp.SetCondition(self.hexdecode(args["condition"]))
|
||||
bp.SetEnabled(int(args["enabled"]))
|
||||
if hasattr(bp, 'SetOneShot'):
|
||||
bp.SetOneShot(int(args["oneshot"]))
|
||||
@@ -1481,7 +1479,7 @@ class Dumper(DumperBase):
|
||||
result = 'memory={cookie="%s",' % args['cookie']
|
||||
result += ',address="%s",' % address
|
||||
result += self.describeError(error)
|
||||
result += ',contents="%s"}' % binascii.hexlify(contents)
|
||||
result += ',contents="%s"}' % self.hexencode(contents)
|
||||
self.report(result)
|
||||
|
||||
def findValueByExpression(self, exp):
|
||||
@@ -1492,8 +1490,8 @@ class Dumper(DumperBase):
|
||||
|
||||
def assignValue(self, args):
|
||||
error = lldb.SBError()
|
||||
exp = binascii.unhexlify(args['exp'])
|
||||
value = binascii.unhexlify(args['value'])
|
||||
exp = self.hexdecode(args['exp'])
|
||||
value = self.hexdecode(args['value'])
|
||||
lhs = self.findValueByExpression(exp)
|
||||
lhs.SetValueFromCString(value, error)
|
||||
self.reportError(error)
|
||||
|
||||
@@ -5011,9 +5011,8 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
||||
dummy.iname = child["iname"].data();
|
||||
GdbMi wname = child["wname"];
|
||||
if (wname.isValid()) {
|
||||
// Happens (only) for watched expressions. They are encoded as
|
||||
// base64 encoded 8 bit data, without quotes
|
||||
dummy.name = decodeData(wname.data(), Base64Encoded8Bit);
|
||||
// Happens (only) for watched expressions.
|
||||
dummy.name = QString::fromUtf8(QByteArray::fromHex(wname.data()));
|
||||
dummy.exp = dummy.name.toUtf8();
|
||||
} else {
|
||||
dummy.name = _(child["name"].data());
|
||||
@@ -5026,7 +5025,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
||||
const GdbMi name = s["name"];
|
||||
const GdbMi size = s["size"];
|
||||
if (name.isValid() && size.isValid())
|
||||
m_typeInfoCache.insert(QByteArray::fromBase64(name.data()),
|
||||
m_typeInfoCache.insert(QByteArray::fromHex(name.data()),
|
||||
TypeInfo(size.data().toUInt()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user