diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 9125b67c39096864c952373ccc86dbed3f913c4c..605452261b3fa14428cced0162773ca921446624 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -1238,7 +1238,7 @@ void CdbDebugEngine::warning(const QString &w) qWarning("%s\n", qPrintable(w)); } -void CdbDebugEnginePrivate::notifyException(long code, bool fatal) +void CdbDebugEnginePrivate::notifyException(long code, bool fatal, const QString &message) { if (debugCDBExecution) qDebug() << "notifyException code" << code << " fatal=" << fatal; @@ -1257,8 +1257,10 @@ void CdbDebugEnginePrivate::notifyException(long code, bool fatal) break; } // Cannot go over crash point to execute calls. - if (fatal) + if (fatal) { m_dumper->disable(); + manager()->showStatusMessage(message, 15000); + } } static int threadIndexById(const ThreadsHandler *threadsHandler, int id) diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h index a4ab5d1acd75c599892265242d484359fb4b5287..34bcb45b9c69061669c26f21dac39592328c30ee 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine_p.h +++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h @@ -92,7 +92,7 @@ public: bool executeContinueCommand(const QString &command); bool attemptBreakpointSynchronization(QString *errorMessage); - void notifyException(long code, bool fatal); + void notifyException(long code, bool fatal, const QString &message); enum EndInferiorAction { DetachInferior, TerminateInferior }; bool endInferior(EndInferiorAction a, QString *errorMessage); diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp index e6b8fc50e59decad5d5add3d0480dd29c5874f92..a7ad1107fd4543bc47774e21bc2b3e7dfd8da1b7 100644 --- a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp +++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp @@ -81,7 +81,7 @@ STDMETHODIMP CdbDebugEventCallback::Exception( qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg; m_pEngine->manager()->showApplicationOutput(msg); m_pEngine->manager()->showDebuggerOutput(LogMisc, msg); - m_pEngine->m_d->notifyException(Exception->ExceptionCode, fatal); + m_pEngine->m_d->notifyException(Exception->ExceptionCode, fatal, msg); return S_OK; } diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp index bac771c15836963fab1eb405af1bc17f447f3c97..c14d5c2a0069e965432d3f41dfafb13013e5dafa 100644 --- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp +++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp @@ -345,12 +345,12 @@ CdbSymbolGroupContext *CdbSymbolGroupContext::create(const QString &prefix, // "0x4343 class list<>". static inline QString fixValue(const QString &value, const QString &type) { - // Pass through strings, chars - if (value.endsWith(QLatin1Char('"')) || value.endsWith(QLatin1Char('\''))) + // Pass through strings + if (value.endsWith(QLatin1Char('"'))) return value; const int size = value.size(); - // Integer numbers Unsigned hex numbers (0x)/decimal numbers (0n) - if (isIntType(type)) { + // Real Integer numbers Unsigned hex numbers (0x)/decimal numbers (0n) + if (type != QLatin1String("bool") && isIntType(type)) { const QVariant intValue = CdbCore::SymbolGroupContext::getIntValue(value); if (intValue.isValid()) return intValue.toString(); @@ -378,10 +378,11 @@ unsigned CdbSymbolGroupContext::watchDataAt(unsigned long index, WatchData *wd) } wd->setAddress(("0x") + QByteArray::number(address, 16)); wd->setType(type, false); - wd->setValue(fixValue(value, type)); if (rc & OutOfScope) { wd->setError(WatchData::msgNotInScope()); } else { + wd->setValue(fixValue(value, type)); + const bool hasChildren = rc & HasChildren; wd->setHasChildren(hasChildren); if (hasChildren) diff --git a/src/plugins/debugger/cdb/symbolgroupcontext.cpp b/src/plugins/debugger/cdb/symbolgroupcontext.cpp index 06f13dceef47fbd8b0ddb4972b6ea4fd7ebe6d1d..28cd87f603247f10d15228d962eb9f3ef206a20e 100644 --- a/src/plugins/debugger/cdb/symbolgroupcontext.cpp +++ b/src/plugins/debugger/cdb/symbolgroupcontext.cpp @@ -440,6 +440,10 @@ bool SymbolGroupContext::getUnsignedHexValue(QString stringValue, quint64 *value if (!stringValue.startsWith(QLatin1String("0x"))) return false; stringValue.remove(0, 2); + // Chop off character values (0x76 'a') + const int blankPos = stringValue.indexOf(QLatin1Char(' ')); + if (blankPos != -1) + stringValue.truncate(blankPos); // Remove 64bit separator if (stringValue.size() > 9) { const int sepPos = stringValue.size() - 9; @@ -473,7 +477,7 @@ QVariant SymbolGroupContext::getIntValue(const QString &stringValue) return QVariant(uvalue); } break; - case '0': // Decimal or none + case '\0': // Decimal or none case 'n': { qint64 nvalue; if (SymbolGroupContext::getDecimalIntValue(stringValue, &nvalue)) @@ -664,6 +668,10 @@ bool SymbolGroupContext::getDecimalIntValue(QString stringValue, qint64 *value) // with Debugging tools v6.12 or later if (stringValue.startsWith(QLatin1String("0n"))) stringValue.remove(0, 2); + // Chop off character values (0n97 'a') + const int blankPos = stringValue.indexOf(QLatin1Char(' ')); + if (blankPos != -1) + stringValue.truncate(blankPos); bool ok; *value = stringValue.toInt(&ok); return ok; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 6b92c0de57c5c2f8a58a2350ba9ddcbb42635251..1d8cf6896a57faa37b9c3bb3954d797ff5d27f27 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -158,6 +158,12 @@ void WatchData::setValue(const QString &value0) value.clear(); hasChildren = true; // at least one... } + // strip off quoted characters for chars. + if (value.endsWith(QLatin1Char('\'')) && type.endsWith(QLatin1String("char"))) { + const int blankPos = value.indexOf(QLatin1Char(' ')); + if (blankPos != -1) + value.truncate(blankPos); + } // avoid duplicated information if (value.startsWith(QLatin1Char('(')) && value.contains(") 0x")) @@ -632,9 +638,43 @@ template <class IntType> QString reformatInteger(IntType value, int format) return QString::number(value); // not reached } -static QString formattedValue(const WatchData &data, int format) +// Format printable (char-type) characters +static inline QString reformatCharacter(int code, int format) +{ + const QString codeS = reformatInteger(code, format); + if (code < 0) // Append unsigned value. + return codeS + QLatin1String(" / ") + reformatInteger(256 + code, format); + if (code >= 32 && code < 128) + return codeS + QLatin1String(" '") + QChar(code) + QLatin1Char('\''); + switch (code) { + case 0: + return codeS + QLatin1String(" '\\0'"); + case '\r': + return codeS + QLatin1String(" '\\r'"); + case '\t': + return codeS + QLatin1String(" '\\t'"); + case '\n': + return codeS + QLatin1String(" '\\n'"); + } + return codeS; +} + +static inline QString formattedValue(const WatchData &data, int format) { if (isIntType(data.type)) { + if (data.value.isEmpty()) + return data.value; + // Do not reformat booleans (reported as 'true, false'). + const QChar firstChar = data.value.at(0); + if (!firstChar.isDigit() && firstChar != QLatin1Char('-')) + return data.value; + // Append quoted, printable character also for decimal. + if (data.type.endsWith(QLatin1String("char"))) { + bool ok; + const int code = data.value.toInt(&ok); + return ok ? reformatCharacter(code, format) : data.value; + } + // Rest: Leave decimal as is if (format <= 0) return data.value; // Evil hack, covers 'unsigned' as well as quint64.