forked from qt-creator/qt-creator
Debugger: Somewhat more robust LLDB output parsing
Change-Id: Ia54d99df15240db4c56fe0ba6b6282319056f59f Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -78,6 +78,23 @@
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
static QByteArray quoteUnprintable(const QByteArray &ba)
|
||||||
|
{
|
||||||
|
QByteArray res;
|
||||||
|
char buf[10];
|
||||||
|
for (int i = 0, n = ba.size(); i != n; ++i) {
|
||||||
|
const unsigned char c = ba.at(i);
|
||||||
|
if (isprint(c)) {
|
||||||
|
res += c;
|
||||||
|
} else {
|
||||||
|
qsnprintf(buf, sizeof(buf) - 1, "\\%02x", int(c));
|
||||||
|
res += buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// LldbEngine
|
// LldbEngine
|
||||||
@@ -124,14 +141,17 @@ void LldbEngine::postCommand(const QByteArray &command,
|
|||||||
const char *callbackName,
|
const char *callbackName,
|
||||||
const QVariant &cookie)
|
const QVariant &cookie)
|
||||||
{
|
{
|
||||||
|
static int token = 0;
|
||||||
|
++token;
|
||||||
QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
|
QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
|
||||||
LldbCommand cmd;
|
LldbCommand cmd;
|
||||||
cmd.command = command;
|
cmd.command = command;
|
||||||
cmd.callback = callback;
|
cmd.callback = callback;
|
||||||
cmd.callbackName = callbackName;
|
cmd.callbackName = callbackName;
|
||||||
cmd.cookie = cookie;
|
cmd.cookie = cookie;
|
||||||
|
cmd.token = token;
|
||||||
m_commands.enqueue(cmd);
|
m_commands.enqueue(cmd);
|
||||||
showMessage(_(cmd.command), LogInput);
|
showMessage(QString::number(token) + _(cmd.command), LogInput);
|
||||||
m_lldbProc.write(cmd.command + '\n');
|
m_lldbProc.write(cmd.command + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,28 +620,56 @@ void LldbEngine::readLldbStandardError()
|
|||||||
//handleOutput(err);
|
//handleOutput(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isEatable(char c)
|
||||||
|
{
|
||||||
|
return c == 10 || c == 13;
|
||||||
|
}
|
||||||
|
|
||||||
void LldbEngine::readLldbStandardOutput()
|
void LldbEngine::readLldbStandardOutput()
|
||||||
{
|
{
|
||||||
QByteArray out = m_lldbProc.readAllStandardOutput();
|
QByteArray out = m_lldbProc.readAllStandardOutput();
|
||||||
showMessage(_("Lldb stdout: " + out));
|
showMessage(_("Lldb stdout: " + out));
|
||||||
qDebug() << "\nLLDB STDOUT" << out;
|
qDebug("\nLLDB RAW STDOUT: '%s'", quoteUnprintable(out).constData());
|
||||||
handleOutput(out);
|
// Remove embedded backspace characters
|
||||||
}
|
int j = 1;
|
||||||
|
const int n = out.size();
|
||||||
|
for (int i = 1; i < n; ++i, ++j) {
|
||||||
|
const char c = out.at(i);
|
||||||
|
if (i != j)
|
||||||
|
out[j] = c;
|
||||||
|
if (c == 8)
|
||||||
|
j -= 2;
|
||||||
|
else if (isEatable(c))
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
if (j != n)
|
||||||
|
out.resize(j);
|
||||||
|
//qDebug("\n\nLLDB STDOUT: '%s'", quoteUnprintable(out).constData());
|
||||||
|
if (out.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
void LldbEngine::handleOutput(const QByteArray &data)
|
|
||||||
{
|
|
||||||
//qDebug() << "READ: " << data;
|
//qDebug() << "READ: " << data;
|
||||||
m_inbuffer.append(data);
|
if (out.startsWith(8)) {
|
||||||
qDebug() << "BUFFER FROM: '" << m_inbuffer << '\'';
|
if (!m_inbuffer.isEmpty())
|
||||||
|
m_inbuffer.chop(1);
|
||||||
|
m_inbuffer.append(out.mid(1));
|
||||||
|
} else if (isEatable(out.at(0))) {
|
||||||
|
m_inbuffer.append(out.mid(1));
|
||||||
|
} else {
|
||||||
|
m_inbuffer.append(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("\nBUFFER FROM: '%s'", quoteUnprintable(m_inbuffer).constData());
|
||||||
while (true) {
|
while (true) {
|
||||||
int pos = m_inbuffer.indexOf("(lldb)");
|
int pos = m_inbuffer.indexOf("(lldb)");
|
||||||
if (pos == -1)
|
if (pos == -1)
|
||||||
break;
|
break;
|
||||||
QByteArray response = m_inbuffer.left(pos).trimmed();
|
QByteArray response = m_inbuffer.left(pos).trimmed();
|
||||||
m_inbuffer = m_inbuffer.mid(pos + 6);
|
m_inbuffer = m_inbuffer.mid(pos + 6);
|
||||||
|
qDebug("\nBUFFER RECOGNIZED: '%s'", quoteUnprintable(response).constData());
|
||||||
emit outputReady(response);
|
emit outputReady(response);
|
||||||
}
|
}
|
||||||
qDebug() << "BUFFER LEFT: '" << m_inbuffer << '\'';
|
qDebug("\nBUFFER LEFT: '%s'", quoteUnprintable(m_inbuffer).constData());
|
||||||
//m_inbuffer.clear();
|
//m_inbuffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +681,7 @@ void LldbEngine::handleOutput2(const QByteArray &data)
|
|||||||
QTC_ASSERT(!m_commands.isEmpty(), qDebug() << "RESPONSE: " << data; return);
|
QTC_ASSERT(!m_commands.isEmpty(), qDebug() << "RESPONSE: " << data; return);
|
||||||
LldbCommand cmd = m_commands.dequeue();
|
LldbCommand cmd = m_commands.dequeue();
|
||||||
response.cookie = cmd.cookie;
|
response.cookie = cmd.cookie;
|
||||||
qDebug() << "DEQUE: " << cmd.command << cmd.callbackName;
|
qDebug("\nDEQUE: '%s' -> '%s'", cmd.command.constData(), cmd.callbackName);
|
||||||
if (cmd.callback) {
|
if (cmd.callback) {
|
||||||
//qDebug() << "EXECUTING CALLBACK " << cmd.callbackName
|
//qDebug() << "EXECUTING CALLBACK " << cmd.callbackName
|
||||||
// << " RESPONSE: " << response.data;
|
// << " RESPONSE: " << response.data;
|
||||||
|
@@ -121,7 +121,6 @@ private:
|
|||||||
Q_SLOT void readLldbStandardError();
|
Q_SLOT void readLldbStandardError();
|
||||||
Q_SLOT void handleOutput2(const QByteArray &data);
|
Q_SLOT void handleOutput2(const QByteArray &data);
|
||||||
void handleResponse(const QByteArray &ba);
|
void handleResponse(const QByteArray &ba);
|
||||||
void handleOutput(const QByteArray &data);
|
|
||||||
void updateAll();
|
void updateAll();
|
||||||
void updateLocals();
|
void updateLocals();
|
||||||
void handleUpdateAll(const LldbResponse &response);
|
void handleUpdateAll(const LldbResponse &response);
|
||||||
@@ -137,15 +136,13 @@ private:
|
|||||||
|
|
||||||
struct LldbCommand
|
struct LldbCommand
|
||||||
{
|
{
|
||||||
LldbCommand()
|
LldbCommand() : callback(0), callbackName(0), token(0) {}
|
||||||
: callback(0), callbackName(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
LldbCommandCallback callback;
|
LldbCommandCallback callback;
|
||||||
const char *callbackName;
|
const char *callbackName;
|
||||||
QByteArray command;
|
QByteArray command;
|
||||||
QVariant cookie;
|
QVariant cookie;
|
||||||
//QTime postTime;
|
int token;
|
||||||
};
|
};
|
||||||
|
|
||||||
void handleStop(const LldbResponse &response);
|
void handleStop(const LldbResponse &response);
|
||||||
|
Reference in New Issue
Block a user