diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp index 58d27ca3a6a..8b6cfd10980 100644 --- a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp +++ b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp @@ -498,6 +498,8 @@ static std::string commmandLocals(ExtensionCommandContext &commandExtCtx,PCSTR a symGroup->markUninitialized(uninitializedInames); SymbolGroupValue::verbose = parameters.verbose; + if (SymbolGroupValue::verbose) + DebugPrint() << parameters.dumpParameters; // Synchronize watches if desired. WatchesSymbolGroup *watchesSymbolGroup = extCtx.watchesSymbolGroup(); diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp index 4ce1a421ab9..d926d19e293 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp @@ -294,6 +294,10 @@ DumpParameters::DumpParameters() : dumpFlags(0) DumpParameters::FormatMap DumpParameters::decodeFormatArgument(const std::string &f, bool isHex) { + extern const char *stdStringTypeC; + extern const char *stdWStringTypeC; + extern const char *stdWStringWCharTypeC; + FormatMap rc; const std::string::size_type size = f.size(); // Split 'hexname=4,' @@ -313,7 +317,13 @@ DumpParameters::FormatMap DumpParameters::decodeFormatArgument(const std::string int format; if (!integerFromString(f.substr(numberPos, nextPos - numberPos), &format)) return rc; - rc.insert(FormatMap::value_type(name, format)); + if (name == "std::basic_string") { // Python dumper naming convention for types + rc.insert(FormatMap::value_type(stdStringTypeC, format)); + rc.insert(FormatMap::value_type(stdWStringTypeC, format)); + rc.insert(FormatMap::value_type(stdWStringWCharTypeC, format)); + } else { + rc.insert(FormatMap::value_type(name, format)); + } pos = nextPos + 1; } return rc; diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 95c3f8780fe..2eaea005c47 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -993,10 +993,10 @@ static inline void formatMilliSeconds(std::wostream &str, int milliSecs) << '.' << std::setw(3) << milliSecs; } -static const char stdStringTypeC[] = "std::basic_string,std::allocator >"; -static const char stdWStringTypeC[] = "std::basic_string,std::allocator >"; +const char *stdStringTypeC = "std::basic_string,std::allocator >"; +const char *stdWStringTypeC = "std::basic_string,std::allocator >"; // Compiler option: -Zc:wchar_t-: -static const char stdWStringWCharTypeC[] = "std::basic_string,std::allocator >"; +const char *stdWStringWCharTypeC = "std::basic_string,std::allocator >"; static KnownType knownPODTypeHelper(const std::string &type, std::string::size_type endPos) { @@ -2206,29 +2206,32 @@ static inline bool dumpQWindow(const SymbolGroupValue &v, std::wostream &str, vo } // Dump a std::string. -static bool dumpStd_W_String(const SymbolGroupValue &v, int type, std::wostream &str) +static bool dumpStd_W_String(const SymbolGroupValue &v, int type, std::wostream &str, + MemoryHandle **memoryHandle = 0) { // Find 'bx'. MSVC 2012 has 2 base classes, MSVC 2010 1, // and MSVC2008 none const SymbolGroupValue bx = SymbolGroupValue::findMember(v, "_Bx"); const int reserved = bx.parent()["_Myres"].intValue(); - if (!bx || reserved < 0) + const int size = bx.parent()["_Mysize"].intValue(); + if (!bx || reserved < 0 || size < 0) return false; // 'Buf' array for small strings, else pointer 'Ptr'. const int bufSize = type == KT_StdString ? 16 : 8; // see basic_string. - const SymbolGroupValue string = bufSize <= reserved ? bx["_Ptr"] : bx["_Buf"]; - if (!string) + const unsigned long memSize = type == KT_StdString ? size : 2 * size; + const ULONG64 address = reserved >= bufSize ? bx["_Ptr"].pointerValue() : bx["_Buf"].address(); + if (!address) return false; - // Potentially re-code char arrays (preferably relying on - // CDB to initially format the string array). - const DumpParameterRecodeResult recode = checkCharArrayRecode(string); - if (recode.buffer) { - str << (type == KT_StdString ? - quotedWStringFromCharData(recode.buffer, recode.size) : - quotedWStringFromWCharData(recode.buffer, recode.size)); - delete [] recode.buffer; + unsigned char *memory = SymbolGroupValue::readMemory(v.context().dataspaces, address, memSize); + if (!memory) + return false; + str << (type == KT_StdString ? + quotedWStringFromCharData(memory, memSize) : + quotedWStringFromWCharData(memory, memSize)); + if (memoryHandle) { + *memoryHandle = new MemoryHandle(memory, memSize); } else { - str << string.value(); + delete [] memory; } return true; } @@ -2590,7 +2593,7 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx, break; case KT_StdString: case KT_StdWString: - rc = dumpStd_W_String(v, kt, str) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed; + rc = dumpStd_W_String(v, kt, str, memoryHandleIn) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed; break; default: break; @@ -2640,11 +2643,13 @@ bool dumpEditValue(const SymbolGroupNode *n, const SymbolGroupValueContext &, switch (n->dumperType()) { case KT_QString: + case KT_StdWString: if (desiredFormat == StringSeparateWindow) if (const MemoryHandle *mh = n->memory()) formatEditValue(DisplayUtf16String, mh, str); break; case KT_QByteArray: + case KT_StdString: if (desiredFormat == StringSeparateWindow) if (const MemoryHandle *mh = n->memory()) formatEditValue(DisplayLatin1String, mh, str); diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 12773901625..383107e5065 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -632,6 +632,7 @@ void CdbEngine::setupEngine() wh->addTypeFormats("QString *", stringFormats); wh->addTypeFormats("QByteArray", stringFormats); wh->addTypeFormats("QByteArray *", stringFormats); + wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string } bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessage)