diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 2aeaadbd9b96f35f6769b17a199951a413e5047c..20456e62881f13243579c5655ed08229fe9f885b 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -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): diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index b219eeeee769f2a07554c7f35a6f6821b2a35256..0cc2f4cde3b9ca8ab17504776874caa82383c8f5 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -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) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 1bf322692d24ead4c63588775a8fb26008bcee8f..96fb131db177b8ad96e257a79ce8581dd781c069 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -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) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2fdb7f336dcbdefce773902de3af314d35dbab43..708f48df15a1b1d48cc6fd6beba13e3a946af8a3 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -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())); } }