diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2010-12-10 10:47:51 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2010-12-10 10:49:11 +0100 |
commit | 985e5d8dd6edef82acee45a5b93eda86755f79b4 (patch) | |
tree | 21e4c49066c7de1692a21196435f3aed32bbb248 /src/libs/qtcreatorcdbext/symbolgroup.cpp | |
parent | 3a4765e27653be17e454a3dd062cb3a8b06851ce (diff) | |
download | qt-creator-985e5d8dd6edef82acee45a5b93eda86755f79b4.tar.gz |
Debugger[New CDB]: Work on recoding char *-pointers.
Latin1/Ucs4. Append hex dump in case non-printable
characters show in default output.
Diffstat (limited to 'src/libs/qtcreatorcdbext/symbolgroup.cpp')
-rw-r--r-- | src/libs/qtcreatorcdbext/symbolgroup.cpp | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/src/libs/qtcreatorcdbext/symbolgroup.cpp b/src/libs/qtcreatorcdbext/symbolgroup.cpp index 39cfc60557..9ad79a2388 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; |