forked from qt-creator/qt-creator
Debugger[TCF]: Parse \u-escapes in JSON correctly, report verbose
crash messages.
This commit is contained in:
@@ -315,8 +315,9 @@ void TcfTrkGdbAdapter::tcftrkEvent(const TcfTrkEvent &e)
|
||||
static_cast<const TcfTrkRunControlContextSuspendedEvent &>(e);
|
||||
const unsigned threadId = RunControlContext::threadIdFromTcdfId(se.id());
|
||||
const QString reason = QString::fromUtf8(se.reasonID());
|
||||
showMessage(_("Reset snapshot (Thread 0x%1 stopped: '%2')").
|
||||
arg(threadId, 0, 16).arg(reason));
|
||||
const QString message = QString::fromUtf8(se.message()).replace(QLatin1String("\n"), QLatin1String(", "));
|
||||
showMessage(_("Thread %1 stopped: '%2': %3").
|
||||
arg(threadId).arg(reason, message), LogMisc);
|
||||
// Stopped in a new thread: Add.
|
||||
m_snapshot.reset();
|
||||
m_session.tid = threadId;
|
||||
@@ -1037,6 +1038,7 @@ void TcfTrkGdbAdapter::setupInferior()
|
||||
|
||||
void TcfTrkGdbAdapter::addThread(unsigned id)
|
||||
{
|
||||
showMessage(QString::fromLatin1("Thread %1 reported").arg(id), LogMisc);
|
||||
// Make thread known, register as main if it is the first one.
|
||||
if (m_snapshot.indexOfThread(id) == -1) {
|
||||
m_snapshot.addThread(id);
|
||||
|
||||
@@ -88,6 +88,7 @@ QByteArray JsonValue::parseNumber(const char *&from, const char *to)
|
||||
QByteArray JsonValue::parseCString(const char *&from, const char *to)
|
||||
{
|
||||
QByteArray result;
|
||||
const char * const fromSaved = from;
|
||||
JDEBUG("parseCString: " << QByteArray(from, to - from));
|
||||
if (*from != '"') {
|
||||
qDebug() << "JSON Parse Error, double quote expected";
|
||||
@@ -105,7 +106,8 @@ QByteArray JsonValue::parseCString(const char *&from, const char *to)
|
||||
if (*ptr == '\\') {
|
||||
++ptr;
|
||||
if (ptr == to) {
|
||||
qDebug() << "JSON Parse Error, unterminated backslash escape";
|
||||
qWarning("JSON Parse Error, unterminated backslash escape in '%s'",
|
||||
QByteArray(fromSaved, to - fromSaved).constData());
|
||||
from = ptr; // So we don't hang
|
||||
return QByteArray();
|
||||
}
|
||||
@@ -130,8 +132,24 @@ QByteArray JsonValue::parseCString(const char *&from, const char *to)
|
||||
case 'v': *dst++ = '\v'; break;
|
||||
case '"': *dst++ = '"'; break;
|
||||
case '\\': *dst++ = '\\'; break;
|
||||
default:
|
||||
{
|
||||
case 'u': { // 4 digit hex escape as in '\u000a'
|
||||
if (end - src < 4) {
|
||||
qWarning("JSON Parse Error, too few hex digits in \\u-escape in '%s' obtained from '%s'",
|
||||
result.constData(), QByteArray(fromSaved, to - fromSaved).constData());
|
||||
return QByteArray();
|
||||
}
|
||||
bool ok;
|
||||
const uchar prod = QByteArray(src, 4).toUInt(&ok, 16);
|
||||
if (!ok) {
|
||||
qWarning("JSON Parse Error, invalid hex digits in \\u-escape in '%s' obtained from '%s'",
|
||||
result.constData(), QByteArray(fromSaved, to - fromSaved).constData());
|
||||
return QByteArray();
|
||||
}
|
||||
*dst++ = prod;
|
||||
src += 4;
|
||||
}
|
||||
break;
|
||||
default: { // Up to 3 decimal digits: Not sure if this is supported in JSON?
|
||||
int chars = 0;
|
||||
uchar prod = 0;
|
||||
forever {
|
||||
@@ -145,7 +163,8 @@ QByteArray JsonValue::parseCString(const char *&from, const char *to)
|
||||
c = *src++;
|
||||
}
|
||||
if (!chars) {
|
||||
qDebug() << "JSON Parse Error, unrecognized backslash escape";
|
||||
qWarning("JSON Parse Error, unrecognized backslash escape in string '%s' obtained from '%s'",
|
||||
result.constData(), QByteArray(fromSaved, to - fromSaved).constData());
|
||||
return QByteArray();
|
||||
}
|
||||
*dst++ = prod;
|
||||
|
||||
@@ -383,14 +383,20 @@ TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const
|
||||
const QByteArray idBA = values.at(0).data();
|
||||
const quint64 pc = values.at(1).data().toULongLong();
|
||||
const QByteArray reasonBA = values.at(2).data();
|
||||
QByteArray messageBA;
|
||||
// Module load: Special
|
||||
if (reasonBA == sharedLibrarySuspendReasonC) {
|
||||
ModuleLoadEventInfo info;
|
||||
if (!info.parse(values.at(3)))
|
||||
return 0;
|
||||
return new TcfTrkRunControlModuleLoadContextSuspendedEvent(idBA, reasonBA, pc, info);
|
||||
} else {
|
||||
// hash containing a 'message'-key with a verbose crash message.
|
||||
if (values.at(3).type() == JsonValue::Object && values.at(3).childCount()
|
||||
&& values.at(3).children().at(0).type() == JsonValue::String)
|
||||
messageBA = values.at(3).children().at(0).data();
|
||||
}
|
||||
return new TcfTrkRunControlContextSuspendedEvent(idBA, reasonBA, pc);
|
||||
return new TcfTrkRunControlContextSuspendedEvent(idBA, reasonBA, messageBA, pc);
|
||||
} // "contextSuspended"
|
||||
if (nameBA == "contextAdded")
|
||||
return TcfTrkRunControlContextAddedEvent::parseEvent(values);
|
||||
@@ -505,8 +511,9 @@ QString TcfTrkRunControlContextRemovedEvent::toString() const
|
||||
// --------------- TcfTrkRunControlContextSuspendedEvent
|
||||
TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(const QByteArray &id,
|
||||
const QByteArray &reason,
|
||||
const QByteArray &message,
|
||||
quint64 pc) :
|
||||
TcfTrkIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason)
|
||||
TcfTrkIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason), m_message(message)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -524,6 +531,8 @@ void TcfTrkRunControlContextSuspendedEvent::format(QTextStream &str) const
|
||||
str << "RunControl: '" << idString() << "' suspended at 0x"
|
||||
<< m_pc << ": '" << m_reason << "'.";
|
||||
str.setIntegerBase(10);
|
||||
if (!m_message.isEmpty())
|
||||
str << " (" <<m_message << ')';
|
||||
}
|
||||
|
||||
QString TcfTrkRunControlContextSuspendedEvent::toString() const
|
||||
|
||||
@@ -262,12 +262,14 @@ public:
|
||||
|
||||
explicit TcfTrkRunControlContextSuspendedEvent(const QByteArray &id,
|
||||
const QByteArray &reason,
|
||||
const QByteArray &message,
|
||||
quint64 pc = 0);
|
||||
virtual QString toString() const;
|
||||
|
||||
quint64 pc() const { return m_pc; }
|
||||
QByteArray reasonID() const { return m_reason; }
|
||||
Reason reason() const;
|
||||
QByteArray message() const { return m_message; }
|
||||
|
||||
protected:
|
||||
explicit TcfTrkRunControlContextSuspendedEvent(Type t,
|
||||
@@ -279,6 +281,7 @@ protected:
|
||||
private:
|
||||
const quint64 m_pc;
|
||||
const QByteArray m_reason;
|
||||
const QByteArray m_message;
|
||||
};
|
||||
|
||||
// RunControlContextSuspended due to module load
|
||||
|
||||
Reference in New Issue
Block a user