forked from qt-creator/qt-creator
Debugger: Progress on LLDB state handling
Change-Id: Iadf9c7026a3da0adeec8340729a303bbbee57c24 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -259,6 +259,7 @@ NamespaceCode = gdb.TYPE_CODE_NAMESPACE
|
|||||||
#Code = gdb.TYPE_CODE_DECFLOAT # Decimal floating point.
|
#Code = gdb.TYPE_CODE_DECFLOAT # Decimal floating point.
|
||||||
#Code = gdb.TYPE_CODE_MODULE # Fortran
|
#Code = gdb.TYPE_CODE_MODULE # Fortran
|
||||||
#Code = gdb.TYPE_CODE_INTERNAL_FUNCTION
|
#Code = gdb.TYPE_CODE_INTERNAL_FUNCTION
|
||||||
|
SimpleValueCode = -1
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|||||||
@@ -109,17 +109,13 @@ class Value:
|
|||||||
def fields(self):
|
def fields(self):
|
||||||
return [Value(self.raw.GetChildAtIndex(i)) for i in range(self.raw.num_children)]
|
return [Value(self.raw.GetChildAtIndex(i)) for i in range(self.raw.num_children)]
|
||||||
|
|
||||||
currentThread = None
|
def currentFrame():
|
||||||
currentFrame = None
|
currentThread = lldb.process.GetThreadAtIndex(0)
|
||||||
|
return currentThread.GetFrameAtIndex(0)
|
||||||
|
|
||||||
def listOfLocals(varList):
|
def listOfLocals(varList):
|
||||||
global currentThread
|
|
||||||
global currentFrame
|
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
currentThread = lldb.process.GetThreadAtIndex(0)
|
for var in currentFrame().variables:
|
||||||
currentFrame = currentThread.GetFrameAtIndex(0)
|
|
||||||
for var in currentFrame.variables:
|
|
||||||
item = LocalItem()
|
item = LocalItem()
|
||||||
item.iname = "local." + var.name
|
item.iname = "local." + var.name
|
||||||
item.name = var.name
|
item.name = var.name
|
||||||
@@ -160,7 +156,7 @@ def threadsData(options):
|
|||||||
result += ",file=\"%s\"" % frame.line_entry.file
|
result += ",file=\"%s\"" % frame.line_entry.file
|
||||||
result += "}},"
|
result += "}},"
|
||||||
|
|
||||||
result += "],current-thread-id=\"%s\"}" % lldb.process.selected_thread.id
|
result += "],current-thread-id=\"%s\"}," % lldb.process.selected_thread.id
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# See lldb.StateType
|
# See lldb.StateType
|
||||||
@@ -256,12 +252,9 @@ def onBreak():
|
|||||||
result = "*stopped,frame={....}"
|
result = "*stopped,frame={....}"
|
||||||
print result
|
print result
|
||||||
|
|
||||||
def handleBreakpoints(opts, toAdd, toChange, toRemove):
|
def handleBreakpoints(options, toAdd, toChange, toRemove):
|
||||||
#todo = json.loads(stuff)
|
|
||||||
#dumpJson(todo)
|
|
||||||
#target = lldb.debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT)
|
#target = lldb.debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT)
|
||||||
target = lldb.debugger.GetTargetAtIndex(0)
|
target = lldb.debugger.GetTargetAtIndex(0)
|
||||||
#target = lldb.target
|
|
||||||
|
|
||||||
result = "result={bkpts={added=["
|
result = "result={bkpts={added=["
|
||||||
|
|
||||||
@@ -282,8 +275,8 @@ def handleBreakpoints(opts, toAdd, toChange, toRemove):
|
|||||||
#"breakpoint command add 1 -o \"import time; print time.asctime()\"
|
#"breakpoint command add 1 -o \"import time; print time.asctime()\"
|
||||||
#cmd = "script print(11111111)"
|
#cmd = "script print(11111111)"
|
||||||
cmd = "continue"
|
cmd = "continue"
|
||||||
lldb.debugger.HandleCommand(
|
#lldb.debugger.HandleCommand(
|
||||||
"breakpoint command add -o 'script onBreak()' %s" % bpNew.GetID())
|
# "breakpoint command add -o 'script onBreak()' %s" % bpNew.GetID())
|
||||||
|
|
||||||
result += dumpBreakpoint(bpNew, bp["modelid"])
|
result += dumpBreakpoint(bpNew, bp["modelid"])
|
||||||
|
|
||||||
@@ -306,127 +299,99 @@ def handleBreakpoints(opts, toAdd, toChange, toRemove):
|
|||||||
result += "]}}"
|
result += "]}}"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def doSync(func):
|
def createStoppedReport(options):
|
||||||
lldb.debugger.SetAsync(False)
|
|
||||||
func()
|
|
||||||
lldb.debugger.SetAsync(True)
|
|
||||||
|
|
||||||
def createReport(options):
|
|
||||||
result = "result={"
|
result = "result={"
|
||||||
result += bb(options["locals"])
|
result += bb(options["locals"]) + ","
|
||||||
result += stackData(options["stack"], lldb.process.selected_thread.id)
|
result += stackData(options["stack"], lldb.process.selected_thread.id)
|
||||||
result += threadsData({})
|
result += threadsData({})
|
||||||
result += stateData({})
|
result += stateData({})
|
||||||
result += locationData({})
|
result += locationData({})
|
||||||
result += "token=\"%s\"" % options["token"]
|
result += "token=\"%s\"," % options["token"]
|
||||||
result += "}"
|
result += "}"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def executeNext(opts):
|
def createRunReport(options):
|
||||||
doSync(lldb.thread.StepOver)
|
result = "result={"
|
||||||
return createReport(opts)
|
#result += stateData({})
|
||||||
|
result += "state=\"running\","
|
||||||
|
result += "token=\"%s\"," % options["token"]
|
||||||
|
result += "}"
|
||||||
|
return result
|
||||||
|
|
||||||
def executeNextI(opts):
|
def createReport(options):
|
||||||
doSync(lldb.thread.StepOver)
|
return createStoppedReport(options)
|
||||||
return createReport(opts)
|
|
||||||
|
|
||||||
def executeStep(opts):
|
def executeNext(options):
|
||||||
lldb.thread.Step()
|
lldb.thread.StepOver()
|
||||||
return createReport(opts)
|
return createRunReport(options)
|
||||||
|
|
||||||
def executeStepI(opts):
|
def executeNextI(options):
|
||||||
doSync(lldb.thread.StepInstOver)
|
lldb.thread.StepOver()
|
||||||
return createReport(opts)
|
return createRunReport(options)
|
||||||
|
|
||||||
def executeStepOut(opts):
|
def executeStep(options):
|
||||||
doSync(lldb.thread.StepOut)
|
lldb.thread.StepInto()
|
||||||
return createReport(opts)
|
return createRunReport(options)
|
||||||
|
|
||||||
def executeRunToLine(opts):
|
def executeStepI(options):
|
||||||
return "result={error={msg='Not implemented'}}"
|
lldb.thread.StepInstOver()
|
||||||
|
return createRunReport(options)
|
||||||
|
|
||||||
def executeJumpToLine(opts):
|
def executeStepOut(options):
|
||||||
return "result={error={msg='Not implemented'}}"
|
lldb.thread.StepOutOfFrame(currentFrame())
|
||||||
|
return createRunReport(options)
|
||||||
|
|
||||||
def continueInferior(opts):
|
def executeRunToLine(options, file, line):
|
||||||
#lldb.debugger.HandleCommand("process continue")
|
lldb.thread.StepOverUntil(file, line)
|
||||||
|
return createRunReport(options)
|
||||||
|
|
||||||
|
def executeJumpToLine(options):
|
||||||
|
return "result={error={msg='Not implemented'},state='stopped'}"
|
||||||
|
|
||||||
|
def continueInferior(options):
|
||||||
lldb.process.Continue()
|
lldb.process.Continue()
|
||||||
return "result={state='running'}"
|
return "result={state=\"running\"}"
|
||||||
|
|
||||||
def interruptInferior(opts):
|
def interruptInferior(options):
|
||||||
lldb.debugger.SetAsync(False)
|
|
||||||
lldb.process.Stop()
|
lldb.process.Stop()
|
||||||
#lldb.process.SendAsyncInterrupt()
|
return "result={state=\"interrupting\"}"
|
||||||
lldb.debugger.SetAsync(True)
|
|
||||||
return createReport()
|
|
||||||
|
|
||||||
def setupInferior(opts, fileName):
|
def setupInferior(options, fileName):
|
||||||
lldb.debugger.HandleCommand("target create '%s'" % fileName)
|
msg = lldb.debugger.HandleCommand("target create '%s'" % fileName)
|
||||||
return "result={state=\"inferiorsetupok\"}"
|
return "result={state=\"inferiorsetupok\",msg=\"%s\"}" % msg
|
||||||
|
|
||||||
def runEngine(opts):
|
def runEngine(options):
|
||||||
lldb.debugger.HandleCommand("process launch")
|
msg = lldb.debugger.HandleCommand("process launch")
|
||||||
return "result={state=\"enginerunok\"}"
|
return "result={state=\"enginerunok\",msg=\"%s\"}" % msg
|
||||||
|
|
||||||
def activateFrame(opts, frame):
|
def activateFrame(options, frame):
|
||||||
lldb.debugger.HandleCommand("frame select " + frame)
|
lldb.debugger.HandleCommand("frame select " + frame)
|
||||||
|
return createStoppedReport(options)
|
||||||
|
|
||||||
def selectThread(opts, thread):
|
def selectThread(options, thread):
|
||||||
lldb.debugger.HandleCommand("thread select " + thread)
|
lldb.debugger.HandleCommand("thread select " + thread)
|
||||||
|
return createStoppedReport(options)
|
||||||
|
|
||||||
def requestModuleSymbols(opts, frame):
|
def requestModuleSymbols(options, frame):
|
||||||
lldb.debugger.HandleCommand("target module list " + frame)
|
lldb.debugger.HandleCommand("target module list " + frame)
|
||||||
|
|
||||||
|
def executeDebuggerCommand(options, command):
|
||||||
|
msg = lldb.debugger.HandleCommand(command)
|
||||||
|
result = "result={"
|
||||||
|
result += bb(options["locals"]) + ","
|
||||||
|
result += stackData(options["stack"], lldb.process.selected_thread.id)
|
||||||
|
result += threadsData({})
|
||||||
|
result += stateData({})
|
||||||
|
result += locationData({})
|
||||||
|
result += "token=\"%s\"," % options["token"]
|
||||||
|
result += "msg=\"%s\"" % msg
|
||||||
|
result += "}"
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
#SBEvent data;
|
|
||||||
#while (!stop) {
|
|
||||||
#if (self->m_listener.WaitForEvent(UINT32_MAX, data)) {
|
|
||||||
# if (data.getType() == SBProcess::eBroadcastBitStateChanged &&
|
|
||||||
#m_process.GetStateFromEvent (data) == eStateStopped) {
|
|
||||||
# SBThread th = m_process.GetSelectedThread();
|
|
||||||
# if (th.GetStopReason() == eStopReasonBreakpoint) {
|
|
||||||
# // th.GetStopReasonDataAtIndex(0) should have the breakpoint id
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
lldb.debugger.HandleCommand("setting set auto-confirm on")
|
lldb.debugger.HandleCommand("setting set auto-confirm on")
|
||||||
lldb.debugger.HandleCommand("setting set interpreter.prompt-on-quit off")
|
lldb.debugger.HandleCommand("setting set interpreter.prompt-on-quit off")
|
||||||
|
|
||||||
if False:
|
|
||||||
# default:
|
|
||||||
# frame-format (string) = "frame #${frame.index}: ${frame.pc}
|
|
||||||
# { ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}
|
|
||||||
# { at ${line.file.basename}:${line.number}}\n"
|
|
||||||
lldb.debugger.HandleCommand("settings set frame-format frame=\{"
|
|
||||||
+ "index='${frame.index}',"
|
|
||||||
+ "pc='${frame.pc}',"
|
|
||||||
+ "module='${module.file.basename}',"
|
|
||||||
#+ "function='${function.name-with-args}',"
|
|
||||||
+ "function='${function.name}',"
|
|
||||||
+ "pcoffset='${function.pc-offset}',"
|
|
||||||
+ "file='${line.file.basename}',"
|
|
||||||
+ "line='${line.number}'"
|
|
||||||
+ "\},")
|
|
||||||
|
|
||||||
|
|
||||||
# default:
|
|
||||||
# "thread #${thread.index}: tid = ${thread.id}{, ${frame.pc}}
|
|
||||||
# { ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}
|
|
||||||
# { at ${line.file.basename}:${line.number}}
|
|
||||||
# {, stop reason = ${thread.stop-reason}}{\nReturn value: ${thread.return-value}}\n"
|
|
||||||
lldb.debugger.HandleCommand("settings set thread-format thread=\{"
|
|
||||||
+ "index='${thread.index}',"
|
|
||||||
+ "tid='${thread.id}',"
|
|
||||||
+ "framepc='${frame.pc}',"
|
|
||||||
+ "module='${module.file.basename}',"
|
|
||||||
+ "function='${function.name}',"
|
|
||||||
+ "pcoffset='${function.pc-offset}',"
|
|
||||||
+ "stopreason='${thread.stop-reason}'"
|
|
||||||
#+ "returnvalue='${thread.return-value}'"
|
|
||||||
+ "\},")
|
|
||||||
|
|
||||||
|
|
||||||
lldbLoaded = True
|
lldbLoaded = True
|
||||||
|
|
||||||
execfile(os.path.join(currentDir, "dumper.py"))
|
execfile(os.path.join(currentDir, "dumper.py"))
|
||||||
|
|||||||
@@ -204,8 +204,16 @@ void LldbEngine::setupInferior()
|
|||||||
void LldbEngine::runEngine()
|
void LldbEngine::runEngine()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
||||||
|
|
||||||
|
QByteArray command;
|
||||||
|
bool done = attemptBreakpointSynchronizationHelper(&command);
|
||||||
|
if (done) {
|
||||||
|
runEngine2();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_continuations.append(&LldbEngine::runEngine2);
|
m_continuations.append(&LldbEngine::runEngine2);
|
||||||
attemptBreakpointSynchronization();
|
runCommand("handleBreakpoints", command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::runEngine2()
|
void LldbEngine::runEngine2()
|
||||||
@@ -329,14 +337,8 @@ bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
|||||||
&& startParameters().startMode != AttachCore;
|
&& startParameters().startMode != AttachCore;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::attemptBreakpointSynchronization()
|
bool LldbEngine::attemptBreakpointSynchronizationHelper(QByteArray *command)
|
||||||
{
|
{
|
||||||
showMessage(_("ATTEMPT BREAKPOINT SYNCHRONIZATION"));
|
|
||||||
if (!stateAcceptsBreakpointChanges()) {
|
|
||||||
showMessage(_("BREAKPOINT SYNCHRONIZATION NOT POSSIBLE IN CURRENT STATE"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BreakHandler *handler = breakHandler();
|
BreakHandler *handler = breakHandler();
|
||||||
|
|
||||||
foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
|
foreach (BreakpointModelId id, handler->unclaimedBreakpointIds()) {
|
||||||
@@ -407,11 +409,24 @@ void LldbEngine::attemptBreakpointSynchronization()
|
|||||||
QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
|
QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!done)
|
||||||
|
*command = '[' + toAdd + "],[" + toChange + "],[" + toRemove + ']';
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LldbEngine::attemptBreakpointSynchronization()
|
||||||
|
{
|
||||||
|
showMessage(_("ATTEMPT BREAKPOINT SYNCHRONIZATION"));
|
||||||
|
if (!stateAcceptsBreakpointChanges()) {
|
||||||
|
showMessage(_("BREAKPOINT SYNCHRONIZATION NOT POSSIBLE IN CURRENT STATE"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray command;
|
||||||
|
bool done = attemptBreakpointSynchronizationHelper(&command);
|
||||||
if (!done) {
|
if (!done) {
|
||||||
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
|
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
|
||||||
runCommand("handleBreakpoints",
|
runCommand("handleBreakpoints", command);
|
||||||
'[' + toAdd + "],[" + toChange + "],[" + toRemove + ']');
|
|
||||||
} else {
|
} else {
|
||||||
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
|
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
|
||||||
}
|
}
|
||||||
@@ -891,6 +906,8 @@ GdbMi LldbEngine::parseResultFromString(QByteArray out)
|
|||||||
out = out.mid(pos);
|
out = out.mid(pos);
|
||||||
if (out.endsWith('\''))
|
if (out.endsWith('\''))
|
||||||
out.chop(1);
|
out.chop(1);
|
||||||
|
else if (out.endsWith('"'))
|
||||||
|
out.chop(1);
|
||||||
else
|
else
|
||||||
showMessage(_("JUNK AT END OF RESPONSE: " + out));
|
showMessage(_("JUNK AT END OF RESPONSE: " + out));
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ private:
|
|||||||
|
|
||||||
bool acceptsBreakpoint(BreakpointModelId id) const;
|
bool acceptsBreakpoint(BreakpointModelId id) const;
|
||||||
void attemptBreakpointSynchronization();
|
void attemptBreakpointSynchronization();
|
||||||
|
bool attemptBreakpointSynchronizationHelper(QByteArray *command);
|
||||||
|
|
||||||
void assignValueInDebugger(const WatchData *data,
|
void assignValueInDebugger(const WatchData *data,
|
||||||
const QString &expr, const QVariant &value);
|
const QString &expr, const QVariant &value);
|
||||||
|
|||||||
Reference in New Issue
Block a user