forked from qt-creator/qt-creator
Debugger: add some food for the threads view in the LLDB backend
Change-Id: I6d8ea11d6c6e1206e5d1c3f13a51ae0521f25a85 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -559,6 +559,53 @@ try:
|
|||||||
def fieldCount(type):
|
def fieldCount(type):
|
||||||
return type.fieldCount();
|
return type.fieldCount();
|
||||||
|
|
||||||
|
def threadsData(threadsOptions):
|
||||||
|
result = "threads={threads=["
|
||||||
|
for i in range(lldb.process.num_threads):
|
||||||
|
thread = lldb.process.GetThreadAtIndex(i)
|
||||||
|
result += "{id=\"%d\"" % thread.id
|
||||||
|
result += ",target-id=\"%s\"" % thread.id
|
||||||
|
result += ",stop-reason=\"%s\"" % thread.stop_reason
|
||||||
|
|
||||||
|
if thread.IsSuspended():
|
||||||
|
result += ",state=\"stopped\""
|
||||||
|
else:
|
||||||
|
result += ",state=\"running\""
|
||||||
|
|
||||||
|
if not thread.name is None:
|
||||||
|
result += ",name=\"%s\"" % thread.name
|
||||||
|
|
||||||
|
result += ",frame={"
|
||||||
|
frame = thread.GetFrameAtIndex(0)
|
||||||
|
result += "pc=\"%s\"" % frame.pc
|
||||||
|
result += ",level=\"%d\"" % i
|
||||||
|
result += ",addr=\"%s\"" % frame.pc
|
||||||
|
result += ",fp=\"%s\"" % frame.fp
|
||||||
|
result += ",func=\"%s\"" % frame.function.name
|
||||||
|
result += ",line=\"%s\"" % frame.line_entry.line
|
||||||
|
result += ",fullname=\"%s\"" % frame.line_entry.file
|
||||||
|
result += ",file=\"%s\"" % frame.line_entry.file
|
||||||
|
result += "}},"
|
||||||
|
|
||||||
|
result += "],current-thread-id=\"%s\"}" % lldb.process.GetSelectedThread().id
|
||||||
|
return result
|
||||||
|
|
||||||
|
def stackData(stackOptions):
|
||||||
|
result = "stack=["
|
||||||
|
result += "],"
|
||||||
|
return result
|
||||||
|
|
||||||
|
def updateData(parts, localsOptions, stackOptions, threadsOptions):
|
||||||
|
result = "";
|
||||||
|
if parts & 1:
|
||||||
|
result += bb(localsOptions) + ','
|
||||||
|
if parts & 2:
|
||||||
|
result += stackData(stackOptions)
|
||||||
|
if parts & 4:
|
||||||
|
result += threadsData(threadsOptions)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
#warn("LOADING LLDB FAILED")
|
#warn("LOADING LLDB FAILED")
|
||||||
pass
|
pass
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
#include "registerhandler.h"
|
#include "registerhandler.h"
|
||||||
#include "stackhandler.h"
|
#include "stackhandler.h"
|
||||||
#include "sourceutils.h"
|
#include "sourceutils.h"
|
||||||
|
#include "threadshandler.h"
|
||||||
#include "watchhandler.h"
|
#include "watchhandler.h"
|
||||||
#include "watchutils.h"
|
#include "watchutils.h"
|
||||||
|
|
||||||
@@ -360,13 +361,13 @@ void LldbEngine::activateFrame(int frameIndex)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
postCommand("frame select " + QByteArray::number(frameIndex),
|
postCommand("frame select " + QByteArray::number(frameIndex),
|
||||||
CB(handleUpdateAll));
|
CB(triggerUpdateAll));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::selectThread(ThreadId threadId)
|
void LldbEngine::selectThread(ThreadId threadId)
|
||||||
{
|
{
|
||||||
postCommand("thread select " + QByteArray::number(threadId.raw()),
|
postCommand("thread select " + QByteArray::number(threadId.raw()),
|
||||||
CB(handleUpdateAll));
|
CB(triggerUpdateAll));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
||||||
@@ -757,7 +758,7 @@ void LldbEngine::handleFirstCommand(const LldbResponse &response)
|
|||||||
Q_UNUSED(response);
|
Q_UNUSED(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleUpdateAll(const LldbResponse &response)
|
void LldbEngine::triggerUpdateAll(const LldbResponse &response)
|
||||||
{
|
{
|
||||||
Q_UNUSED(response);
|
Q_UNUSED(response);
|
||||||
updateAll();
|
updateAll();
|
||||||
@@ -765,12 +766,16 @@ void LldbEngine::handleUpdateAll(const LldbResponse &response)
|
|||||||
|
|
||||||
void LldbEngine::updateAll()
|
void LldbEngine::updateAll()
|
||||||
{
|
{
|
||||||
//postCommand("bt", CB(handleBacktrace));
|
updateData(DataKind(LocalsData | StackData | ThreadData));
|
||||||
updateLocals();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::updateLocals()
|
void LldbEngine::updateData(DataKind kind)
|
||||||
{
|
{
|
||||||
|
QByteArray localsOptions;
|
||||||
|
QByteArray stackOptions;
|
||||||
|
QByteArray threadsOptions;
|
||||||
|
|
||||||
|
if (kind & LocalsData) {
|
||||||
QByteArray watchers;
|
QByteArray watchers;
|
||||||
//if (!m_toolTipExpression.isEmpty())
|
//if (!m_toolTipExpression.isEmpty())
|
||||||
// watchers += m_toolTipExpression.toLatin1()
|
// watchers += m_toolTipExpression.toLatin1()
|
||||||
@@ -795,13 +800,19 @@ void LldbEngine::updateLocals()
|
|||||||
options += "defaults,";
|
options += "defaults,";
|
||||||
options.chop(1);
|
options.chop(1);
|
||||||
|
|
||||||
postCommand("script bb('options:" + options + " "
|
localsOptions = "options:" + options + " "
|
||||||
+ "vars: "
|
+ "vars: "
|
||||||
+ "expanded:" + handler->expansionRequests() + " "
|
+ "expanded:" + handler->expansionRequests() + " "
|
||||||
+ "typeformats:" + handler->typeFormatRequests() + " "
|
+ "typeformats:" + handler->typeFormatRequests() + " "
|
||||||
+ "formats:" + handler->individualFormatRequests() + " "
|
+ "formats:" + handler->individualFormatRequests() + " "
|
||||||
+ "watcher:" + watchers.toHex() + "')",
|
+ "watcher:" + watchers.toHex();
|
||||||
CB(handleListLocals));
|
}
|
||||||
|
|
||||||
|
postCommand("script updateData(" + QByteArray::number(kind) + ','
|
||||||
|
+ '\'' + localsOptions + "',"
|
||||||
|
+ '\'' + stackOptions + "',"
|
||||||
|
+ '\'' + threadsOptions + "')",
|
||||||
|
CB(handleUpdateData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleBacktrace(const LldbResponse &response)
|
void LldbEngine::handleBacktrace(const LldbResponse &response)
|
||||||
@@ -847,19 +858,17 @@ void LldbEngine::handleBacktrace(const LldbResponse &response)
|
|||||||
gotoLocation(stackFrames.at(currentIndex));
|
gotoLocation(stackFrames.at(currentIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLocals();
|
updateData(LocalsData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleListLocals(const LldbResponse &response)
|
GdbMi LldbEngine::parseFromString(QByteArray out)
|
||||||
{
|
{
|
||||||
//qDebug() << " LOCALS: '" << response.data << "'";
|
GdbMi all;
|
||||||
QByteArray out = response.data;
|
|
||||||
|
|
||||||
{
|
|
||||||
int pos = out.indexOf("data=");
|
int pos = out.indexOf("data=");
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
showMessage(_("UNEXPECTED LOCALS OUTPUT:" + out));
|
showMessage(_("UNEXPECTED LOCALS OUTPUT:" + out));
|
||||||
return;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The value in 'out' should be single-quoted as this is
|
// The value in 'out' should be single-quoted as this is
|
||||||
@@ -873,12 +882,18 @@ void LldbEngine::handleListLocals(const LldbResponse &response)
|
|||||||
out.chop(1);
|
out.chop(1);
|
||||||
else
|
else
|
||||||
showMessage(_("JUNK AT END OF RESPONSE: " + out));
|
showMessage(_("JUNK AT END OF RESPONSE: " + out));
|
||||||
}
|
|
||||||
|
|
||||||
GdbMi all;
|
|
||||||
all.fromStringMultiple(out);
|
all.fromStringMultiple(out);
|
||||||
GdbMi data = all.findChild("data");
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LldbEngine::handleUpdateData(const LldbResponse &response)
|
||||||
|
{
|
||||||
|
//qDebug() << " LOCALS: '" << response.data << "'";
|
||||||
|
GdbMi all = parseFromString(response.data);
|
||||||
|
|
||||||
|
GdbMi vars = all.findChild("data");
|
||||||
|
if (vars.isValid()) {
|
||||||
const bool partial = response.cookie.toBool();
|
const bool partial = response.cookie.toBool();
|
||||||
WatchHandler *handler = watchHandler();
|
WatchHandler *handler = watchHandler();
|
||||||
QList<WatchData> list;
|
QList<WatchData> list;
|
||||||
@@ -889,7 +904,7 @@ void LldbEngine::handleListLocals(const LldbResponse &response)
|
|||||||
list.append(*handler->findData("return"));
|
list.append(*handler->findData("return"));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const GdbMi &child, data.children()) {
|
foreach (const GdbMi &child, vars.children()) {
|
||||||
WatchData dummy;
|
WatchData dummy;
|
||||||
dummy.iname = child.findChild("iname").data();
|
dummy.iname = child.findChild("iname").data();
|
||||||
GdbMi wname = child.findChild("wname");
|
GdbMi wname = child.findChild("wname");
|
||||||
@@ -903,6 +918,9 @@ void LldbEngine::handleListLocals(const LldbResponse &response)
|
|||||||
}
|
}
|
||||||
parseWatchData(handler->expandedINames(), dummy, child, &list);
|
parseWatchData(handler->expandedINames(), dummy, child, &list);
|
||||||
}
|
}
|
||||||
|
handler->insertData(list);
|
||||||
|
}
|
||||||
|
|
||||||
// const GdbMi typeInfo = all.findChild("typeinfo");
|
// const GdbMi typeInfo = all.findChild("typeinfo");
|
||||||
// if (typeInfo.type() == GdbMi::List) {
|
// if (typeInfo.type() == GdbMi::List) {
|
||||||
// foreach (const GdbMi &s, typeInfo.children()) {
|
// foreach (const GdbMi &s, typeInfo.children()) {
|
||||||
@@ -919,11 +937,23 @@ void LldbEngine::handleListLocals(const LldbResponse &response)
|
|||||||
// list[i].size = ti.size;
|
// list[i].size = ti.size;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
handler->insertData(list);
|
GdbMi stack = all.findChild("stack");
|
||||||
|
if (stack.isValid()) {
|
||||||
|
//if (!partial)
|
||||||
|
// emit stackFrameCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
//rebuildWatchModel();
|
GdbMi threads = all.findChild("threads");
|
||||||
if (!partial)
|
if (threads.isValid()) {
|
||||||
emit stackFrameCompleted();
|
ThreadsHandler *handler = threadsHandler();
|
||||||
|
handler->updateThreads(threads);
|
||||||
|
if (!handler->currentThread().isValid()) {
|
||||||
|
ThreadId other = handler->threadAt(0);
|
||||||
|
if (other.isValid())
|
||||||
|
selectThread(other);
|
||||||
|
}
|
||||||
|
updateViews(); // Adjust Threads combobox.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::loadPythonDumpers()
|
void LldbEngine::loadPythonDumpers()
|
||||||
|
@@ -121,10 +121,13 @@ private:
|
|||||||
Q_SLOT void handleOutput2(const QByteArray &data);
|
Q_SLOT void handleOutput2(const QByteArray &data);
|
||||||
void handleResponse(const QByteArray &ba);
|
void handleResponse(const QByteArray &ba);
|
||||||
|
|
||||||
|
enum DataKind { LocalsData = 1, StackData = 2, ThreadData = 4 };
|
||||||
|
|
||||||
void loadPythonDumpers();
|
void loadPythonDumpers();
|
||||||
void updateAll();
|
void updateAll();
|
||||||
void updateLocals();
|
void updateData(DataKind kind);
|
||||||
void handleUpdateAll(const LldbResponse &response);
|
void triggerUpdateAll(const LldbResponse &response);
|
||||||
|
void handleUpdateData(const LldbResponse &response);
|
||||||
void handleFirstCommand(const LldbResponse &response);
|
void handleFirstCommand(const LldbResponse &response);
|
||||||
void handleExecuteDebuggerCommand(const LldbResponse &response);
|
void handleExecuteDebuggerCommand(const LldbResponse &response);
|
||||||
void handleInferiorSetup(const LldbResponse &response);
|
void handleInferiorSetup(const LldbResponse &response);
|
||||||
@@ -152,6 +155,8 @@ private:
|
|||||||
void handleListModules(const LldbResponse &response);
|
void handleListModules(const LldbResponse &response);
|
||||||
void handleListSymbols(const LldbResponse &response);
|
void handleListSymbols(const LldbResponse &response);
|
||||||
void handleBreakInsert(const LldbResponse &response);
|
void handleBreakInsert(const LldbResponse &response);
|
||||||
|
void handleUpdateStack(const LldbResponse &response);
|
||||||
|
void handleUpdateThreads(const LldbResponse &response);
|
||||||
|
|
||||||
void handleChildren(const WatchData &data0, const GdbMi &item,
|
void handleChildren(const WatchData &data0, const GdbMi &item,
|
||||||
QList<WatchData> *list);
|
QList<WatchData> *list);
|
||||||
@@ -160,6 +165,7 @@ private:
|
|||||||
const char *callbackName = 0,
|
const char *callbackName = 0,
|
||||||
const QVariant &cookie = QVariant());
|
const QVariant &cookie = QVariant());
|
||||||
void postDirectCommand(const QByteArray &command);
|
void postDirectCommand(const QByteArray &command);
|
||||||
|
GdbMi parseFromString(QByteArray out);
|
||||||
|
|
||||||
QQueue<LldbCommand> m_commands;
|
QQueue<LldbCommand> m_commands;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user