Commit 83e1fcfd authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger[TCF]: Parse \u-escapes in JSON correctly, report verbose

crash messages.
parent e871b7e3
......@@ -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
......
Supports Markdown
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