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()));
             }
         }