Commit 2b9a00f1 authored by hjk's avatar hjk

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: default avatarhjk <hjk121@nokiamail.com>
parent 88a4421a
......@@ -56,31 +56,29 @@ except:
return "Normal"
def bytesToString(b):
if sys.version_info[0] == 2:
return b
return b.decode("utf8")
def stringToBytes(s):
if sys.version_info[0] == 2:
return s
return s.encode("utf8")
# Base 16 decoding operating on string->string
def b16decode(s):
return bytesToString(base64.b16decode(stringToBytes(s), True))
# Base 16 decoding operating on string->string
def b16encode(s):
return bytesToString(base64.b16encode(stringToBytes(s)))
# Base 64 decoding operating on string->string
def b64decode(s):
return bytesToString(base64.b64decode(stringToBytes(s)))
class Blob(object):
"""
Helper structure to keep a blob of bytes, possibly
in the inferior.
"""
def __init__(self, data, isComplete = True):
self.data = data
self.size = len(data)
self.isComplete = isComplete
def size(self):
return self.size
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 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):
......
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()));
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment