Commit b2ddf720 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

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
parent b1b493ce
......@@ -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)
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment