From b2ddf72035ffa50295b78715b0401ca48eb0f64c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Fri, 9 Apr 2010 16:39:36 +0200 Subject: [PATCH] Debugger[cdb/gdb]: Fix formatting of integers/messages. - Do not reformat boolean values (true,false) as hex/oct. - char/unsigned char types (cdb/gdb): Chop off the quoted printable character output by the debugger, pass around integer only and append the character ourselves in the watchhandler, making reformatting as hex/octal work. - cdb: Check format correctly (fix values output as plain integer). - cdb: Kill needless warning produced by reformatting output of out-of-scope variables. - cdb: Display exceptions in the status bar as non-intrusive crash notification. Reviewed-by: hjk --- src/plugins/debugger/cdb/cdbdebugengine.cpp | 6 ++- src/plugins/debugger/cdb/cdbdebugengine_p.h | 2 +- .../debugger/cdb/cdbdebugeventcallback.cpp | 2 +- .../debugger/cdb/cdbsymbolgroupcontext.cpp | 11 ++--- .../debugger/cdb/symbolgroupcontext.cpp | 10 ++++- src/plugins/debugger/watchhandler.cpp | 42 ++++++++++++++++++- 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 9125b67c390..605452261b3 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 a4ab5d1acd7..34bcb45b9c6 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 e6b8fc50e59..a7ad1107fd4 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 bac771c1583..c14d5c2a006 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 06f13dceef4..28cd87f6032 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 6b92c0de57c..1d8cf6896a5 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. -- GitLab