forked from qt-creator/qt-creator
Debugger: Streamline LLDB input
All options are passed as python hash now. Change-Id: I1caa049a0f5d49ece4b65e5f560b30a2443070a5 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -297,7 +297,7 @@ class Debugger(cmd.Cmd):
|
|||||||
else:
|
else:
|
||||||
self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, fileName))
|
self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, fileName))
|
||||||
|
|
||||||
def runEngine(self):
|
def do_runEngine(self, args):
|
||||||
error = lldb.SBError()
|
error = lldb.SBError()
|
||||||
#launchInfo = lldb.SBLaunchInfo(["-s"])
|
#launchInfo = lldb.SBLaunchInfo(["-s"])
|
||||||
#self.process = self.target.Launch(self.listener, None, None,
|
#self.process = self.target.Launch(self.listener, None, None,
|
||||||
@@ -513,7 +513,7 @@ class Debugger(cmd.Cmd):
|
|||||||
|
|
||||||
def describeBreakpoint(self, bp, modelId):
|
def describeBreakpoint(self, bp, modelId):
|
||||||
cond = bp.GetCondition()
|
cond = bp.GetCondition()
|
||||||
result = '{lldbid="%s"' % bp.GetID()
|
result = 'lldbid="%s"' % bp.GetID()
|
||||||
result += ',modelid="%s"' % modelId
|
result += ',modelid="%s"' % modelId
|
||||||
result += ',hitcount="%s"' % bp.GetHitCount()
|
result += ',hitcount="%s"' % bp.GetHitCount()
|
||||||
result += ',threadid="%s"' % bp.GetThreadID()
|
result += ',threadid="%s"' % bp.GetThreadID()
|
||||||
@@ -536,13 +536,16 @@ class Debugger(cmd.Cmd):
|
|||||||
result += ',valid="%s"' % (1 if loc.IsValid() else 0)
|
result += ',valid="%s"' % (1 if loc.IsValid() else 0)
|
||||||
result += ',ignorecount="%s"' % loc.GetIgnoreCount()
|
result += ',ignorecount="%s"' % loc.GetIgnoreCount()
|
||||||
result += ',addr="%s"},' % loc.GetLoadAddress()
|
result += ',addr="%s"},' % loc.GetLoadAddress()
|
||||||
result += ']},'
|
result += '],'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def handleBreakpoints(self, toAdd, toChange, toRemove):
|
def do_handleBreakpoints(self, args):
|
||||||
result = "bkpts={added=["
|
options = eval(args)
|
||||||
|
result = 'bkpts=['
|
||||||
|
for bp in options['bkpts']:
|
||||||
|
operation = bp['operation']
|
||||||
|
|
||||||
for bp in toAdd:
|
if operation == 'add':
|
||||||
bpType = bp["type"]
|
bpType = bp["type"]
|
||||||
if bpType == BreakpointByFileAndLine:
|
if bpType == BreakpointByFileAndLine:
|
||||||
bpNew = self.target.BreakpointCreateByLocation(str(bp["file"]), int(bp["line"]))
|
bpNew = self.target.BreakpointCreateByLocation(str(bp["file"]), int(bp["line"]))
|
||||||
@@ -566,11 +569,9 @@ class Debugger(cmd.Cmd):
|
|||||||
#cmd = "continue"
|
#cmd = "continue"
|
||||||
#self.debugger.HandleCommand(
|
#self.debugger.HandleCommand(
|
||||||
# "breakpoint command add -o 'script onBreak()' %s" % bpNew.GetID())
|
# "breakpoint command add -o 'script onBreak()' %s" % bpNew.GetID())
|
||||||
result += self.describeBreakpoint(bpNew, bp["modelid"])
|
result += '{operation="added",%s}' % self.describeBreakpoint(bpNew, bp["modelid"])
|
||||||
|
|
||||||
result += "],changed=["
|
elif operation == 'change':
|
||||||
|
|
||||||
for bp in toChange:
|
|
||||||
bpChange = self.target.FindBreakpointByID(int(bp["lldbid"]))
|
bpChange = self.target.FindBreakpointByID(int(bp["lldbid"]))
|
||||||
bpChange.SetIgnoreCount(int(bp["ignorecount"]))
|
bpChange.SetIgnoreCount(int(bp["ignorecount"]))
|
||||||
bpChange.SetCondition(str(bp["condition"]))
|
bpChange.SetCondition(str(bp["condition"]))
|
||||||
@@ -579,17 +580,16 @@ class Debugger(cmd.Cmd):
|
|||||||
bpChange.SetOneShot(int(bp["oneshot"]))
|
bpChange.SetOneShot(int(bp["oneshot"]))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
result += self.describeBreakpoint(bpChange, bp["modelid"])
|
result += '{operation="changed",%s' % self.describeBreakpoint(bpNew, bp["modelid"])
|
||||||
|
|
||||||
result += "],removed=["
|
elif operation == 'remove':
|
||||||
|
|
||||||
for bp in toRemove:
|
|
||||||
bpDead = self.target.BreakpointDelete(int(bp["lldbid"]))
|
bpDead = self.target.BreakpointDelete(int(bp["lldbid"]))
|
||||||
result += '{modelid="%s"}' % bp["modelid"]
|
result += '{operation="removed",modelid="%s"}' % bp["modelid"]
|
||||||
|
|
||||||
result += "]}"
|
result += "]"
|
||||||
self.report(result)
|
self.report(result)
|
||||||
|
|
||||||
|
|
||||||
def listModules(self):
|
def listModules(self):
|
||||||
result = 'modules=['
|
result = 'modules=['
|
||||||
for module in self.target.modules:
|
for module in self.target.modules:
|
||||||
@@ -697,15 +697,8 @@ class Debugger(cmd.Cmd):
|
|||||||
|
|
||||||
# Qt Creator internal
|
# Qt Creator internal
|
||||||
def do_setupInferior(self, args):
|
def do_setupInferior(self, args):
|
||||||
fileName = eval(args)
|
options = eval(args)
|
||||||
self.setupInferior(fileName)
|
self.setupInferior(options['executable'])
|
||||||
|
|
||||||
def do_handleBreakpoints(self, args):
|
|
||||||
toAdd, toChange, toRemove = eval(args)
|
|
||||||
self.handleBreakpoints(toAdd, toChange, toRemove)
|
|
||||||
|
|
||||||
def do_runEngine(self, args):
|
|
||||||
self.runEngine()
|
|
||||||
|
|
||||||
def do_interrupt(self, args):
|
def do_interrupt(self, args):
|
||||||
self.interruptInferior()
|
self.interruptInferior()
|
||||||
@@ -717,7 +710,7 @@ class Debugger(cmd.Cmd):
|
|||||||
self.reportData()
|
self.reportData()
|
||||||
|
|
||||||
# Convenience
|
# Convenience
|
||||||
def do_bb(self, args):
|
def do_updateData(self, args):
|
||||||
options = eval(args)
|
options = eval(args)
|
||||||
self.expandedINames = set(options['expanded'].split(','))
|
self.expandedINames = set(options['expanded'].split(','))
|
||||||
self.reportData()
|
self.reportData()
|
||||||
@@ -782,11 +775,15 @@ if __name__ == '__main__':
|
|||||||
if rlist:
|
if rlist:
|
||||||
line = sys.stdin.readline()
|
line = sys.stdin.readline()
|
||||||
if line.startswith("db "):
|
if line.startswith("db "):
|
||||||
(cmd, token, extra, cont) = eval(line[3:])
|
options = eval(line[3:])
|
||||||
db.onecmd("%s %s" % (cmd, extra))
|
cmd = options['cmd']
|
||||||
db.report('token="%s"' % token)
|
db.onecmd("%s %s" % (cmd, line[3:]))
|
||||||
if len(cont):
|
db.report('token="%s"' % options['token'])
|
||||||
|
try:
|
||||||
|
cont = options['continuation']
|
||||||
db.report('continuation="%s"' % cont)
|
db.report('continuation="%s"' % cont)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
db.onecmd(line)
|
db.onecmd(line)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -103,15 +103,12 @@ void LldbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguage
|
|||||||
|
|
||||||
static int token = 1;
|
static int token = 1;
|
||||||
|
|
||||||
void LldbEngine::runCommand(const QByteArray &functionName,
|
void LldbEngine::runCommand(const Command &command)
|
||||||
const QByteArray &extraArgs, const QByteArray &continuation)
|
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
|
QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
|
||||||
++token;
|
++token;
|
||||||
QByteArray cmd = "db ['" + functionName + "',"
|
QByteArray cmd = "db {'cmd':'" + command.function + "',"
|
||||||
+ QByteArray::number(token) + ","
|
+ command.args + "'token':" + QByteArray::number(token) + "}\n";
|
||||||
+ "'" + extraArgs + "',"
|
|
||||||
+ "'" + continuation + "']\n";
|
|
||||||
showMessage(QString::number(token) + _(cmd), LogInput);
|
showMessage(QString::number(token) + _(cmd), LogInput);
|
||||||
m_lldbProc.write(cmd);
|
m_lldbProc.write(cmd);
|
||||||
}
|
}
|
||||||
@@ -132,8 +129,8 @@ void LldbEngine::setupEngine()
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
||||||
|
|
||||||
m_lldb = startParameters().debuggerCommand;
|
m_lldbBridge = startParameters().debuggerCommand;
|
||||||
showMessage(_("STARTING LLDB ") + m_lldb);
|
showMessage(_("STARTING LLDB ") + m_lldbBridge);
|
||||||
|
|
||||||
connect(&m_lldbProc, SIGNAL(error(QProcess::ProcessError)),
|
connect(&m_lldbProc, SIGNAL(error(QProcess::ProcessError)),
|
||||||
SLOT(handleLldbError(QProcess::ProcessError)));
|
SLOT(handleLldbError(QProcess::ProcessError)));
|
||||||
@@ -148,11 +145,11 @@ void LldbEngine::setupEngine()
|
|||||||
SLOT(handleResponse(QByteArray)), Qt::QueuedConnection);
|
SLOT(handleResponse(QByteArray)), Qt::QueuedConnection);
|
||||||
|
|
||||||
//m_lldbProc.start(m_lldb);
|
//m_lldbProc.start(m_lldb);
|
||||||
m_lldbProc.start(_("/usr/bin/python"), QStringList() << _("-i") << m_lldb);
|
m_lldbProc.start(_("/usr/bin/python"), QStringList() << _("-i") << m_lldbBridge);
|
||||||
|
|
||||||
if (!m_lldbProc.waitForStarted()) {
|
if (!m_lldbProc.waitForStarted()) {
|
||||||
const QString msg = tr("Unable to start lldb '%1': %2")
|
const QString msg = tr("Unable to start lldb '%1': %2")
|
||||||
.arg(m_lldb, m_lldbProc.errorString());
|
.arg(m_lldbBridge, m_lldbProc.errorString());
|
||||||
notifyEngineSetupFailed();
|
notifyEngineSetupFailed();
|
||||||
showMessage(_("ADAPTER START FAILED"));
|
showMessage(_("ADAPTER START FAILED"));
|
||||||
if (!msg.isEmpty())
|
if (!msg.isEmpty())
|
||||||
@@ -162,20 +159,21 @@ void LldbEngine::setupEngine()
|
|||||||
|
|
||||||
void LldbEngine::setupInferior()
|
void LldbEngine::setupInferior()
|
||||||
{
|
{
|
||||||
QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
|
QString executable = QFileInfo(startParameters().executable).absoluteFilePath();
|
||||||
runCommand("setupInferior", '"' + fileName.toUtf8() + '"');
|
runCommand(Command("setupInferior").arg("executable", executable));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::runEngine()
|
void LldbEngine::runEngine()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
||||||
|
|
||||||
QByteArray command;
|
Command cmd("handleBreakpoints");
|
||||||
bool done = attemptBreakpointSynchronizationHelper(&command);
|
if (attemptBreakpointSynchronizationHelper(&cmd)) {
|
||||||
if (done)
|
|
||||||
runEngine2();
|
runEngine2();
|
||||||
else
|
} else {
|
||||||
runCommand("handleBreakpoints", command, "runEngine2");
|
cmd.arg("continuation", "runEngine2");
|
||||||
|
runCommand(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::runEngine2()
|
void LldbEngine::runEngine2()
|
||||||
@@ -276,23 +274,23 @@ void LldbEngine::executeRunToLine(const ContextData &data)
|
|||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
runCommand("executeRunToLine", QByteArray::number(data.address)
|
runCommand(Command("executeRunToLine")
|
||||||
+ ",'" + data.fileName.toUtf8() + "'");
|
.arg("file", data.fileName).arg("line", data.address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeRunToFunction(const QString &functionName)
|
void LldbEngine::executeRunToFunction(const QString &functionName)
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
runCommand("executeRunToFunction", '"' + functionName.toUtf8() + '"');
|
runCommand(Command("executeRunToFunction").arg("function", functionName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeJumpToLine(const ContextData &data)
|
void LldbEngine::executeJumpToLine(const ContextData &data)
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
runCommand("executeJumpToLine", QByteArray::number(data.address)
|
runCommand(Command("executeJumpToLine")
|
||||||
+ ',' + data.fileName.toUtf8());
|
.arg("file", data.fileName).arg("line", data.address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::activateFrame(int frameIndex)
|
void LldbEngine::activateFrame(int frameIndex)
|
||||||
@@ -301,12 +299,12 @@ void LldbEngine::activateFrame(int frameIndex)
|
|||||||
if (state() != InferiorStopOk && state() != InferiorUnrunnable)
|
if (state() != InferiorStopOk && state() != InferiorUnrunnable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
runCommand("activateFrame", QByteArray::number(frameIndex));
|
runCommand(Command("activateFrame").arg("index", frameIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::selectThread(ThreadId threadId)
|
void LldbEngine::selectThread(ThreadId threadId)
|
||||||
{
|
{
|
||||||
runCommand("selectThread", QByteArray::number(threadId.raw()));
|
runCommand(Command("selectThread").arg("id", threadId.raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
||||||
@@ -315,7 +313,7 @@ bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
|||||||
&& startParameters().startMode != AttachCore;
|
&& startParameters().startMode != AttachCore;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LldbEngine::attemptBreakpointSynchronizationHelper(QByteArray *command)
|
bool LldbEngine::attemptBreakpointSynchronizationHelper(Command *cmd)
|
||||||
{
|
{
|
||||||
BreakHandler *handler = breakHandler();
|
BreakHandler *handler = breakHandler();
|
||||||
|
|
||||||
@@ -331,11 +329,8 @@ bool LldbEngine::attemptBreakpointSynchronizationHelper(QByteArray *command)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray toAdd;
|
|
||||||
QByteArray toChange;
|
|
||||||
QByteArray toRemove;
|
|
||||||
|
|
||||||
bool done = true;
|
bool done = true;
|
||||||
|
cmd->beginList("bkpts");
|
||||||
foreach (BreakpointModelId id, handler->engineBreakpointIds(this)) {
|
foreach (BreakpointModelId id, handler->engineBreakpointIds(this)) {
|
||||||
const BreakpointResponse &response = handler->response(id);
|
const BreakpointResponse &response = handler->response(id);
|
||||||
switch (handler->state(id)) {
|
switch (handler->state(id)) {
|
||||||
@@ -345,35 +340,44 @@ bool LldbEngine::attemptBreakpointSynchronizationHelper(QByteArray *command)
|
|||||||
break;
|
break;
|
||||||
case BreakpointInsertRequested:
|
case BreakpointInsertRequested:
|
||||||
done = false;
|
done = false;
|
||||||
toAdd += "{\"modelid\":" + id.toByteArray();
|
cmd->beginGroup()
|
||||||
toAdd += ",\"type\":" + QByteArray::number(handler->type(id));
|
.arg("operation", "add")
|
||||||
toAdd += ",\"ignorecount\":" + QByteArray::number(handler->ignoreCount(id));
|
.arg("modelid", id.toByteArray())
|
||||||
toAdd += ",\"condition\":\"" + handler->condition(id) + '"';
|
.arg("type", handler->type(id))
|
||||||
toAdd += ",\"function\":\"" + handler->functionName(id).toUtf8() + '"';
|
.arg("ignorecount", handler->ignoreCount(id))
|
||||||
toAdd += ",\"oneshot\":" + QByteArray::number(int(handler->isOneShot(id)));
|
.arg("condition", handler->condition(id))
|
||||||
toAdd += ",\"enabled\":" + QByteArray::number(int(handler->isEnabled(id)));
|
.arg("function", handler->functionName(id).toUtf8())
|
||||||
toAdd += ",\"file\":\"" + handler->fileName(id).toUtf8() + '"';
|
.arg("oneshot", handler->isOneShot(id))
|
||||||
toAdd += ",\"line\":" + QByteArray::number(handler->lineNumber(id)) + "},";
|
.arg("enabled", handler->isEnabled(id))
|
||||||
|
.arg("file", handler->fileName(id).toUtf8())
|
||||||
|
.arg("line", handler->lineNumber(id))
|
||||||
|
.endGroup();
|
||||||
handler->notifyBreakpointInsertProceeding(id);
|
handler->notifyBreakpointInsertProceeding(id);
|
||||||
break;
|
break;
|
||||||
case BreakpointChangeRequested:
|
case BreakpointChangeRequested:
|
||||||
done = false;
|
done = false;
|
||||||
toChange += "{\"modelid\":" + id.toByteArray();
|
cmd->beginGroup()
|
||||||
toChange += ",\"lldbid\":" + response.id.toByteArray();
|
.arg("operation", "change")
|
||||||
toChange += ",\"type\":" + QByteArray::number(handler->type(id));
|
.arg("modelid", id.toByteArray())
|
||||||
toChange += ",\"ignorecount\":" + QByteArray::number(handler->ignoreCount(id));
|
.arg("lldbid", response.id.toByteArray())
|
||||||
toChange += ",\"condition\":\"" + handler->condition(id) + '"';
|
.arg("type", handler->type(id))
|
||||||
toChange += ",\"function\":\"" + handler->functionName(id).toUtf8() + '"';
|
.arg("ignorecount", handler->ignoreCount(id))
|
||||||
toChange += ",\"oneshot\":" + QByteArray::number(int(handler->isOneShot(id)));
|
.arg("condition", handler->condition(id))
|
||||||
toChange += ",\"enabled\":" + QByteArray::number(int(handler->isEnabled(id)));
|
.arg("function", handler->functionName(id).toUtf8())
|
||||||
toChange += ",\"file\":\"" + handler->fileName(id).toUtf8() + '"';
|
.arg("oneshot", handler->isOneShot(id))
|
||||||
toChange += ",\"line\":" + QByteArray::number(handler->lineNumber(id)) + "},";
|
.arg("enabled", handler->isEnabled(id))
|
||||||
|
.arg("file", handler->fileName(id).toUtf8())
|
||||||
|
.arg("line", handler->lineNumber(id))
|
||||||
|
.endGroup();
|
||||||
handler->notifyBreakpointChangeProceeding(id);
|
handler->notifyBreakpointChangeProceeding(id);
|
||||||
break;
|
break;
|
||||||
case BreakpointRemoveRequested:
|
case BreakpointRemoveRequested:
|
||||||
done = false;
|
done = false;
|
||||||
toRemove += "{\"modelid\":" + id.toByteArray();
|
cmd->beginGroup()
|
||||||
toRemove += ",\"lldbid\":" + response.id.toByteArray() + "},";
|
.arg("operation", "remove")
|
||||||
|
.arg("modelid", id.toByteArray())
|
||||||
|
.arg("lldbid", response.id.toByteArray())
|
||||||
|
.endGroup();
|
||||||
handler->notifyBreakpointRemoveProceeding(id);
|
handler->notifyBreakpointRemoveProceeding(id);
|
||||||
break;
|
break;
|
||||||
case BreakpointChangeProceeding:
|
case BreakpointChangeProceeding:
|
||||||
@@ -387,8 +391,7 @@ bool LldbEngine::attemptBreakpointSynchronizationHelper(QByteArray *command)
|
|||||||
QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
|
QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!done)
|
cmd->endList();
|
||||||
*command = '[' + toAdd + "],[" + toChange + "],[" + toRemove + ']';
|
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,11 +403,10 @@ void LldbEngine::attemptBreakpointSynchronization()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray command;
|
Command cmd("handleBreakpoints");
|
||||||
bool done = attemptBreakpointSynchronizationHelper(&command);
|
if (!attemptBreakpointSynchronizationHelper(&cmd)) {
|
||||||
if (!done) {
|
|
||||||
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
|
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
|
||||||
runCommand("handleBreakpoints", command);
|
runCommand(cmd);
|
||||||
} else {
|
} else {
|
||||||
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
|
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
|
||||||
}
|
}
|
||||||
@@ -491,25 +493,23 @@ void LldbEngine::refreshMemory(const GdbMi &data)
|
|||||||
void LldbEngine::refreshBreakpoints(const GdbMi &bkpts)
|
void LldbEngine::refreshBreakpoints(const GdbMi &bkpts)
|
||||||
{
|
{
|
||||||
BreakHandler *handler = breakHandler();
|
BreakHandler *handler = breakHandler();
|
||||||
GdbMi added = bkpts["added"];
|
foreach (const GdbMi &bkpt, bkpts.children()) {
|
||||||
GdbMi changed = bkpts["changed"];
|
QByteArray op = bkpt["operation"].data();
|
||||||
GdbMi removed = bkpts["removed"];
|
if (op == "added") {
|
||||||
foreach (const GdbMi &bkpt, added.children()) {
|
|
||||||
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
|
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
|
||||||
QTC_CHECK(handler->state(id) == BreakpointInsertProceeding);
|
QTC_CHECK(handler->state(id) == BreakpointInsertProceeding);
|
||||||
updateBreakpointData(bkpt, true);
|
updateBreakpointData(bkpt, true);
|
||||||
}
|
} else if (op == "changed") {
|
||||||
foreach (const GdbMi &bkpt, changed.children()) {
|
|
||||||
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
|
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
|
||||||
QTC_CHECK(handler->state(id) == BreakpointChangeProceeding);
|
QTC_CHECK(handler->state(id) == BreakpointChangeProceeding);
|
||||||
updateBreakpointData(bkpt, false);
|
updateBreakpointData(bkpt, false);
|
||||||
}
|
} else if (op == "removed") {
|
||||||
foreach (const GdbMi &bkpt, removed.children()) {
|
|
||||||
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
|
BreakpointModelId id = BreakpointModelId(bkpt["modelid"].data());
|
||||||
QTC_CHECK(handler->state(id) == BreakpointRemoveProceeding);
|
QTC_CHECK(handler->state(id) == BreakpointRemoveProceeding);
|
||||||
handler->notifyBreakpointRemoveOk(id);
|
handler->notifyBreakpointRemoveOk(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LldbEngine::loadSymbols(const QString &moduleName)
|
void LldbEngine::loadSymbols(const QString &moduleName)
|
||||||
{
|
{
|
||||||
@@ -544,7 +544,7 @@ void LldbEngine::refreshModules(const GdbMi &modules)
|
|||||||
|
|
||||||
void LldbEngine::requestModuleSymbols(const QString &moduleName)
|
void LldbEngine::requestModuleSymbols(const QString &moduleName)
|
||||||
{
|
{
|
||||||
runCommand("requestModuleSymbols", '"' + moduleName.toUtf8() + '"');
|
runCommand(Command("requestModuleSymbols").arg("module", moduleName.toUtf8()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleListSymbols(const QByteArray &response)
|
void LldbEngine::handleListSymbols(const QByteArray &response)
|
||||||
@@ -672,7 +672,7 @@ void LldbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &
|
|||||||
Q_UNUSED(data);
|
Q_UNUSED(data);
|
||||||
Q_UNUSED(flags);
|
Q_UNUSED(flags);
|
||||||
WatchHandler *handler = watchHandler();
|
WatchHandler *handler = watchHandler();
|
||||||
runCommand("bb", "{'expanded':'" + handler->expansionRequests() + "'}");
|
runCommand(Command("updateData").arg("expanded", handler->expansionRequests()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleLldbError(QProcess::ProcessError error)
|
void LldbEngine::handleLldbError(QProcess::ProcessError error)
|
||||||
@@ -702,7 +702,7 @@ QString LldbEngine::errorMessage(QProcess::ProcessError error) const
|
|||||||
return tr("The Lldb process failed to start. Either the "
|
return tr("The Lldb process failed to start. Either the "
|
||||||
"invoked program '%1' is missing, or you may have insufficient "
|
"invoked program '%1' is missing, or you may have insufficient "
|
||||||
"permissions to invoke the program.")
|
"permissions to invoke the program.")
|
||||||
.arg(m_lldb);
|
.arg(m_lldbBridge);
|
||||||
case QProcess::Crashed:
|
case QProcess::Crashed:
|
||||||
return tr("The Lldb process crashed some time after starting "
|
return tr("The Lldb process crashed some time after starting "
|
||||||
"successfully.");
|
"successfully.");
|
||||||
@@ -742,8 +742,6 @@ void LldbEngine::readLldbStandardOutput()
|
|||||||
{
|
{
|
||||||
QByteArray out = m_lldbProc.readAllStandardOutput();
|
QByteArray out = m_lldbProc.readAllStandardOutput();
|
||||||
showMessage(_("Lldb stdout: " + out));
|
showMessage(_("Lldb stdout: " + out));
|
||||||
//qDebug("\nLLDB RAW STDOUT: '%s'", quoteUnprintable(out).constData());
|
|
||||||
//qDebug("\nBUFFER FROM: '%s'", quoteUnprintable(m_inbuffer).constData());
|
|
||||||
m_inbuffer.append(out);
|
m_inbuffer.append(out);
|
||||||
while (true) {
|
while (true) {
|
||||||
int pos = m_inbuffer.indexOf("@\n");
|
int pos = m_inbuffer.indexOf("@\n");
|
||||||
@@ -751,11 +749,8 @@ void LldbEngine::readLldbStandardOutput()
|
|||||||
break;
|
break;
|
||||||
QByteArray response = m_inbuffer.left(pos).trimmed();
|
QByteArray response = m_inbuffer.left(pos).trimmed();
|
||||||
m_inbuffer = m_inbuffer.mid(pos + 2);
|
m_inbuffer = m_inbuffer.mid(pos + 2);
|
||||||
//qDebug("\nBUFFER RECOGNIZED: '%s'", quoteUnprintable(response).constData());
|
|
||||||
//showMessage(_(response));
|
|
||||||
emit outputReady(response);
|
emit outputReady(response);
|
||||||
}
|
}
|
||||||
//qDebug("\nBUFFER LEFT: '%s'", quoteUnprintable(m_inbuffer).constData());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray LldbEngine::currentOptions() const
|
QByteArray LldbEngine::currentOptions() const
|
||||||
@@ -959,7 +954,7 @@ void LldbEngine::fetchDisassembler(DisassemblerAgent *agent)
|
|||||||
id = ++m_lastAgentId;
|
id = ++m_lastAgentId;
|
||||||
m_disassemblerAgents.insert(p, id);
|
m_disassemblerAgents.insert(p, id);
|
||||||
}
|
}
|
||||||
runCommand("disassemble", "{\"cookie\":" + QByteArray::number(id) + "}");
|
runCommand(Command("disassemble").arg("cookie", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -972,10 +967,10 @@ void LldbEngine::fetchMemory(MemoryAgent *agent, QObject *editorToken,
|
|||||||
m_memoryAgents.insert(agent, id);
|
m_memoryAgents.insert(agent, id);
|
||||||
m_memoryAgentTokens.insert(id, editorToken);
|
m_memoryAgentTokens.insert(id, editorToken);
|
||||||
}
|
}
|
||||||
runCommand("readMemory",
|
runCommand(Command("readMemory")
|
||||||
"{\"address\":" + QByteArray::number(addr) +
|
.arg("address", addr)
|
||||||
",\"length\":" + QByteArray::number(length) +
|
.arg("length", length)
|
||||||
",\"cookie\":" + QByteArray::number(id) + "}");
|
.arg("cookie", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::changeMemory(MemoryAgent *agent, QObject *editorToken,
|
void LldbEngine::changeMemory(MemoryAgent *agent, QObject *editorToken,
|
||||||
@@ -987,16 +982,16 @@ void LldbEngine::changeMemory(MemoryAgent *agent, QObject *editorToken,
|
|||||||
m_memoryAgents.insert(agent, id);
|
m_memoryAgents.insert(agent, id);
|
||||||
m_memoryAgentTokens.insert(id, editorToken);
|
m_memoryAgentTokens.insert(id, editorToken);
|
||||||
}
|
}
|
||||||
runCommand("writeMemory",
|
runCommand(Command("writeMemory")
|
||||||
"{\"address\":" + QByteArray::number(addr) + "" +
|
.arg("address", addr)
|
||||||
",\"data\":\"" + data.toHex() + "\"" +
|
.arg("data", data.toHex())
|
||||||
",\"cookie\":" + QByteArray::number(id) + "}");
|
.arg("cookie", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::setRegisterValue(int regnr, const QString &value)
|
void LldbEngine::setRegisterValue(int regnr, const QString &value)
|
||||||
{
|
{
|
||||||
Register reg = registerHandler()->registers().at(regnr);
|
Register reg = registerHandler()->registers().at(regnr);
|
||||||
runCommand("setRegister " + reg.name + ' ' + value.toLatin1());
|
runCommand(Command("setRegister").arg("name", reg.name).arg("value", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1040,5 +1035,78 @@ DebuggerEngine *createLldbEngine(const DebuggerStartParameters &startParameters)
|
|||||||
return new LldbEngine(startParameters);
|
return new LldbEngine(startParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Command
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const LldbEngine::Command &LldbEngine::Command::arg(const char *name, int value) const
|
||||||
|
{
|
||||||
|
args.append('\'');
|
||||||
|
args.append(name);
|
||||||
|
args.append("':");
|
||||||
|
args.append(QByteArray::number(value));
|
||||||
|
args.append(',');
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const QString &value) const
|
||||||
|
{
|
||||||
|
return arg(name, value.toUtf8().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const QByteArray &value) const
|
||||||
|
{
|
||||||
|
return arg(name, value.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const char *value) const
|
||||||
|
{
|
||||||
|
args.append('\'');
|
||||||
|
args.append(name);
|
||||||
|
args.append("':'");
|
||||||
|
args.append(value);
|
||||||
|
args.append("',");
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LldbEngine::Command &LldbEngine::Command::beginList(const char *name) const
|
||||||
|
{
|
||||||
|
if (name) {
|
||||||
|
args += '\'';
|
||||||
|
args += name;
|
||||||
|
args += "':";
|
||||||
|
}
|
||||||
|
args += '[';
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LldbEngine::Command::endList() const
|
||||||
|
{
|
||||||
|
if (args.endsWith(','))
|
||||||
|
args.chop(1);
|
||||||
|
args += "],";
|
||||||
|
}
|
||||||
|
|
||||||
|
const LldbEngine::Command &LldbEngine::Command::beginGroup(const char *name) const
|
||||||
|
{
|
||||||
|
if (name) {
|
||||||
|
args += '\'';
|
||||||
|
args += name;
|
||||||
|
args += "':";
|
||||||
|
}
|
||||||
|
args += '{';
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LldbEngine::Command::endGroup() const
|
||||||
|
{
|
||||||
|
if (args.endsWith(','))
|
||||||
|
args.chop(1);
|
||||||
|
args += "},";
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ namespace Internal {
|
|||||||
class WatchData;
|
class WatchData;
|
||||||
class GdbMi;
|
class GdbMi;
|
||||||
|
|
||||||
/* A debugger engine for using the lldb command line debugger.
|
/* A debugger engine interfacing the LLDB debugger
|
||||||
|
* using its Python interface.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class LldbEngine : public DebuggerEngine
|
class LldbEngine : public DebuggerEngine
|
||||||
@@ -60,6 +61,25 @@ public:
|
|||||||
~LldbEngine();
|
~LldbEngine();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Convenience struct to build up backend commands.
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
Command() {}
|
||||||
|
Command(const char *f) : function(f) {}
|
||||||
|
|
||||||
|
const Command &arg(const char *name, int value) const;
|
||||||
|
const Command &arg(const char *name, const QString &value) const;
|
||||||
|
const Command &arg(const char *name, const QByteArray &value) const;
|
||||||
|
const Command &arg(const char *name, const char *value) const;
|
||||||
|
const Command &beginList(const char *name = 0) const;
|
||||||
|
void endList() const;
|
||||||
|
const Command &beginGroup(const char *name = 0) const;
|
||||||
|
void endGroup() const;
|
||||||
|
|
||||||
|
QByteArray function;
|
||||||
|
mutable QByteArray args;
|
||||||
|
};
|
||||||
|
|
||||||
// DebuggerEngine implementation
|
// DebuggerEngine implementation
|
||||||
void executeStep();
|
void executeStep();
|
||||||
void executeStepOut();
|
void executeStepOut();
|
||||||
@@ -88,7 +108,7 @@ private:
|
|||||||
|
|
||||||
bool acceptsBreakpoint(BreakpointModelId id) const;
|
bool acceptsBreakpoint(BreakpointModelId id) const;
|
||||||
void attemptBreakpointSynchronization();
|
void attemptBreakpointSynchronization();
|
||||||
bool attemptBreakpointSynchronizationHelper(QByteArray *command);
|
bool attemptBreakpointSynchronizationHelper(Command *command);
|
||||||
|
|
||||||
void assignValueInDebugger(const WatchData *data,
|
void assignValueInDebugger(const WatchData *data,
|
||||||
const QString &expr, const QVariant &value);
|
const QString &expr, const QVariant &value);
|
||||||
@@ -142,13 +162,6 @@ private:
|
|||||||
|
|
||||||
typedef void (LldbEngine::*LldbCommandContinuation)();
|
typedef void (LldbEngine::*LldbCommandContinuation)();
|
||||||
|
|
||||||
struct LldbCommand
|
|
||||||
{
|
|
||||||
LldbCommand() : token(0) {}
|
|
||||||
QByteArray command;
|
|
||||||
int token;
|
|
||||||
};
|
|
||||||
|
|
||||||
QByteArray currentOptions() const;
|
QByteArray currentOptions() const;
|
||||||
void handleStop(const QByteArray &response);
|
void handleStop(const QByteArray &response);
|
||||||
void handleListLocals(const QByteArray &response);
|
void handleListLocals(const QByteArray &response);
|
||||||
@@ -161,14 +174,13 @@ private:
|
|||||||
|
|
||||||
void handleChildren(const WatchData &data0, const GdbMi &item,
|
void handleChildren(const WatchData &data0, const GdbMi &item,
|
||||||
QList<WatchData> *list);
|
QList<WatchData> *list);
|
||||||
void runCommand(const QByteArray &function,
|
|
||||||
const QByteArray &extraArgs = QByteArray(),
|
void runCommand(const Command &cmd);
|
||||||
const QByteArray &continuation = QByteArray());
|
|
||||||
|
|
||||||
QByteArray m_inbuffer;
|
QByteArray m_inbuffer;
|
||||||
QString m_scriptFileName;
|
QString m_scriptFileName;
|
||||||
QProcess m_lldbProc;
|
QProcess m_lldbProc;
|
||||||
QString m_lldb;
|
QString m_lldbBridge;
|
||||||
|
|
||||||
// FIXME: Make generic.
|
// FIXME: Make generic.
|
||||||
int m_lastAgentId;
|
int m_lastAgentId;
|
||||||
|
|||||||
Reference in New Issue
Block a user