diff --git a/src/libs/qtcreatorcdbext/base64.cpp b/src/libs/qtcreatorcdbext/base64.cpp
index d6121daafc0ba78c50182faace9878fe85e3302f..f7f4d37aacc00fffd0152bb3762b8369534dfebc 100644
--- a/src/libs/qtcreatorcdbext/base64.cpp
+++ b/src/libs/qtcreatorcdbext/base64.cpp
@@ -29,9 +29,10 @@
 
 #include "base64.h"
 
-#include <ostream>
+#include <sstream>
 
-static void base64EncodeTriple(std::ostream &str, const unsigned char triple[3], size_t length = 3)
+template <class OStream>
+static void base64EncodeTriple(OStream &str, const unsigned char triple[3], size_t length = 3)
 {
     static const char base64Encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
@@ -57,7 +58,8 @@ static void base64EncodeTriple(std::ostream &str, const unsigned char triple[3],
         str << '=';
 }
 
-void base64Encode(std::ostream &str, const unsigned char *source, size_t sourcelen)
+template <class OStream>
+void base64EncodeHelper(OStream &str, const unsigned char *source, size_t sourcelen)
 {
     if (!sourcelen) {
         str << "====";
@@ -78,3 +80,27 @@ void base64Encode(std::ostream &str, const unsigned char *source, size_t sourcel
         }
     }
 }
+
+void base64Encode(std::ostream &str, const unsigned char *source, size_t sourcelen)
+{
+    base64EncodeHelper(str, source, sourcelen);
+}
+
+std::string base64EncodeToString(const unsigned char *source, size_t sourcelen)
+{
+    std::ostringstream str;
+    base64Encode(str, source, sourcelen);
+    return str.str();
+}
+
+void base64EncodeW(std::wostream &str, const unsigned char *source, size_t sourcelen)
+{
+    base64EncodeHelper(str, source, sourcelen);
+}
+
+std::wstring base64EncodeToWString(const unsigned char *source, size_t sourcelen)
+{
+    std::wostringstream str;
+    base64EncodeW(str, source, sourcelen);
+    return str.str();
+}
diff --git a/src/libs/qtcreatorcdbext/base64.h b/src/libs/qtcreatorcdbext/base64.h
index bfafc2b41176a17191b8066841b8c3b5e298721b..8954cc06d5f9d25e3e2b29eb7a30b8d8e6c1b231 100644
--- a/src/libs/qtcreatorcdbext/base64.h
+++ b/src/libs/qtcreatorcdbext/base64.h
@@ -31,8 +31,12 @@
 #define BASE64_H
 
 #include <iosfwd>
+#include <string>
 
-// Base 64 encoding helper
+// Base 64 encoding helpers
 void base64Encode(std::ostream &str, const unsigned char *source, size_t sourcelen);
+std::string base64EncodeToString(const unsigned char *source, size_t sourcelen);
+void base64EncodeW(std::wostream &str, const unsigned char *source, size_t sourcelen);
+std::wstring base64EncodeToWString(const unsigned char *source, size_t sourcelen);
 
 #endif // BASE64_H
diff --git a/src/libs/qtcreatorcdbext/stringutils.cpp b/src/libs/qtcreatorcdbext/stringutils.cpp
index dfc2d0ad08e315dfc8ae41e3e7f73eab76263486..5491f218ef51a6268250c54004dcde9263dc9414 100644
--- a/src/libs/qtcreatorcdbext/stringutils.cpp
+++ b/src/libs/qtcreatorcdbext/stringutils.cpp
@@ -234,6 +234,23 @@ std::wstring dataToHexW(const unsigned char *p, const unsigned char *end)
     return rc;
 }
 
+// Readable hex: '0xAA 0xBB'..
+std::wstring dataToReadableHexW(const unsigned char *begin, const unsigned char *end)
+{
+    if (begin == end)
+        return std::wstring();
+
+    std::wstring rc;
+    rc.reserve(5 * (end - begin));
+    for (const unsigned char *p = begin; p < end ; p++) {
+        rc.append(p == begin ? L"0x" : L" 0x");
+        const unsigned c = *p;
+        rc.push_back(toHexDigit(c / 16));
+        rc.push_back(toHexDigit(c &0xF));
+    }
+    return rc;
+}
+
 // Format a map as a GDBMI hash {key="value",..}
 void formatGdbmiHash(std::ostream &os, const std::map<std::string, std::string> &m)
 {
diff --git a/src/libs/qtcreatorcdbext/stringutils.h b/src/libs/qtcreatorcdbext/stringutils.h
index 9a0bd40c435c9c1d6f08d550143860a3ec0e137f..f041f8d46a848620047a2932b4d21ea0c2e20d26 100644
--- a/src/libs/qtcreatorcdbext/stringutils.h
+++ b/src/libs/qtcreatorcdbext/stringutils.h
@@ -143,6 +143,8 @@ std::wstring stringToWString(const std::string &w);
 // String from hex "414A" -> "AJ".
 std::string stringFromHex(const char *begin, const char *end);
 std::wstring dataToHexW(const unsigned char *begin, const unsigned char *end);
+// Create readable hex: '0xAA 0xBB'..
+std::wstring dataToReadableHexW(const unsigned char *begin, const unsigned char *end);
 
 // Format a map as a GDBMI hash {key="value",..}
 void formatGdbmiHash(std::ostream &os, const std::map<std::string, std::string> &);
diff --git a/src/libs/qtcreatorcdbext/symbolgroup.cpp b/src/libs/qtcreatorcdbext/symbolgroup.cpp
index 39cfc60557a9d44eb6da6f716468bf450b4b3073..9ad79a238863c00c9ede2cc63d6de126000e58b3 100644
--- a/src/libs/qtcreatorcdbext/symbolgroup.cpp
+++ b/src/libs/qtcreatorcdbext/symbolgroup.cpp
@@ -125,7 +125,7 @@ int DumpParameters::format(const std::string &type, const std::string &iname) co
 
 enum PointerFormats // Watch data pointer format requests
 {
-    FormatRawPointer = 0,
+    FormatAuto = 0,
     FormatLatin1String = 1,
     FormatUtf8String = 2,
     FormatUtf16String = 3,
@@ -139,7 +139,7 @@ enum DumpEncoding // WatchData encoding of GDBMI values
     DumpEncodingBase64_Utf16 = 2,
     DumpEncodingBase64_Ucs4 = 3,
     DumpEncodingHex_Latin1 = 6,
-    DumpEncodingHex_Utf161 = 7,
+    DumpEncodingHex_Utf16 = 7,
     DumpEncodingHex_Ucs4_LittleEndian = 8,
     DumpEncodingHex_Utf8_LittleEndian = 9,
     DumpEncodingHex_Ucs4_BigEndian = 10,
@@ -147,34 +147,57 @@ enum DumpEncoding // WatchData encoding of GDBMI values
     DumpEncodingHex_Utf16_LittleEndian = 12
 };
 
+/* Recode arrays/pointers of char*, wchar_t according to users
+ * sepcification. Handles char formats for 'char *', '0x834478 "hallo.."'
+ * and 'wchar_t *', '0x834478 "hallo.."'.
+ * This is done by retrieving the address and the length (in characters)
+ * of the CDB output, converting it to memory size, fetching the data
+ * from memory, zero-terminating and recoding it using the encoding
+ * defined in watchutils.cpp.
+ * As a special case, if there is no user-defined format and the
+ * CDB output contains '?' indicating non-printable characters,
+ * append a hex dump of the memory (auto-format). */
+
 bool DumpParameters::recode(const std::string &type,
                             const std::string &iname,
                             const SymbolGroupValueContext &ctx,
                             std::wstring *value, int *encoding) const
 {
     // We basically handle char formats for 'char *', '0x834478 "hallo.."'
+    // and 'wchar_t *', '0x834478 "hallo.."'
     // Determine address and length from the pointer value output,
     // read the raw memory and recode if that is possible.
-    const int newFormat = format(type, iname);
-    if (newFormat < 2)
+    if (type.empty() || type.at(type.size() - 1) != '*')
         return false;
+    const int newFormat = format(type, iname);
     if (value->compare(0, 2, L"0x"))
         return false;
     const std::wstring::size_type quote1 = value->find(L'"', 2);
     if (quote1 == std::wstring::npos)
         return false;
+    // The user did not specify any format, still, there are '?'
+    // (indicating non-printable) in what the debugger prints. In that case,
+    // append a hex dump to the normal output. If there are no '?'-> all happy.
+    if (newFormat < FormatLatin1String && value->find(L'?', quote1 + 1) == std::wstring::npos)
+        return false;
     const std::wstring::size_type quote2 = value->find(L'"', quote1 + 1);
     if (quote2 == std::wstring::npos)
         return false;
-    const std::wstring::size_type length = quote2 - quote1 - 1;
+    std::wstring::size_type length = quote2 - quote1 - 1;
     if (!length)
         return false;
+    // Get address from value
     ULONG64 address = 0;
     if (!integerFromWString(value->substr(0, quote1 - 1), &address) || !address)
         return false;
-    // Allocate real length + 4 bytes ('\0') for largest format.
+    // Get real size if this is for example a wchar_t *.
+    const unsigned elementSize = SymbolGroupValue::sizeOf(SymbolGroupValue::stripPointerType(type).c_str());
+    if (!elementSize)
+        return false;
+    length *= elementSize;
+    // Allocate real length + 8 bytes ('\0') for largest format (Ucs4).
     // '\0' is not listed in the CDB output.
-    const std::wstring::size_type allocLength = length + 4;
+    const std::wstring::size_type allocLength = length + 8;
     unsigned char *buffer = new unsigned char[allocLength];
     std::fill(buffer, buffer + allocLength, 0);
     ULONG obtained = 0;
@@ -184,13 +207,35 @@ bool DumpParameters::recode(const std::string &type,
     }
     // Recode raw memory
     switch (newFormat) {
+    case FormatLatin1String:
+        *value = dataToHexW(buffer, buffer + length + 1); // Latin1 + 0
+        *encoding = DumpEncodingHex_Latin1;
+        break;
     case FormatUtf8String:
         *value = dataToHexW(buffer, buffer + length + 1); // UTF8 + 0
         *encoding = DumpEncodingHex_Utf8_LittleEndian;
         break;
-    case FormatUtf16String:
+    case FormatUtf16String: // Paranoia: make sure buffer is terminated at 2 byte borders
+        if (length % 2) {
+            length &= ~1;
+            buffer[length] = '\0';
+            buffer[length + 1] = '\0';
+        }
+        *value = base64EncodeToWString(buffer, length + 2);
+        *encoding = DumpEncodingBase64_Utf16;
+        break;
+    case FormatUcs4String: // Paranoia: make sure buffer is terminated at 4 byte borders
+        if (length % 4) {
+            length &= ~3;
+            std::fill(buffer + length, buffer + length + 4, 0);
+        }
+        *value = dataToHexW(buffer, buffer + length + 2); // UTF16 + 0
+        *encoding = DumpEncodingHex_Ucs4_LittleEndian;
         break;
-    case FormatUcs4String:
+    default:  // See above, append hex dump
+        value->push_back(' ');
+        value->append(dataToReadableHexW(buffer, buffer + length));
+        *encoding = DumpEncodingAscii;
         break;
     }
     delete [] buffer;