forked from qt-creator/qt-creator
Debugger: Centralize LLDB response handling
Most logic is now moved to the python side, so response structure can be uniform Change-Id: Ic06760e33415ca4e05b6a4b3629028c01f304238 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -53,7 +53,6 @@ if False:
|
|||||||
try:
|
try:
|
||||||
import cdb_bridge
|
import cdb_bridge
|
||||||
cdbLoaded = True
|
cdbLoaded = True
|
||||||
|
|
||||||
except:
|
except:
|
||||||
failReasons.append(traceback.format_exc())
|
failReasons.append(traceback.format_exc())
|
||||||
|
|
||||||
@@ -61,8 +60,8 @@ if False:
|
|||||||
if not cdbLoaded:
|
if not cdbLoaded:
|
||||||
try:
|
try:
|
||||||
import gdb
|
import gdb
|
||||||
gdbLoaded = True
|
|
||||||
execfile(os.path.join(currentDir, "gbridge.py"))
|
execfile(os.path.join(currentDir, "gbridge.py"))
|
||||||
|
gdbLoaded = True
|
||||||
except:
|
except:
|
||||||
failReasons.append(traceback.format_exc())
|
failReasons.append(traceback.format_exc())
|
||||||
|
|
||||||
|
@@ -121,6 +121,9 @@ def threadsData(options):
|
|||||||
result += "],current-thread-id=\"%s\"}" % lldb.process.selected_thread.id
|
result += "],current-thread-id=\"%s\"}" % lldb.process.selected_thread.id
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def stateData(options):
|
||||||
|
result = "state={},"
|
||||||
|
|
||||||
def stackData(options):
|
def stackData(options):
|
||||||
try:
|
try:
|
||||||
thread = lldb.process.GetThreadById(options["threadid"])
|
thread = lldb.process.GetThreadById(options["threadid"])
|
||||||
@@ -153,17 +156,18 @@ def parseOptions(optionstring):
|
|||||||
return options
|
return options
|
||||||
|
|
||||||
def updateData(parts, localsOptions, stackOptions, threadOptions):
|
def updateData(parts, localsOptions, stackOptions, threadOptions):
|
||||||
result = "";
|
result = "result={";
|
||||||
if parts & 1:
|
if parts & 1:
|
||||||
result += bb(localsOptions) + ","
|
result += bb(localsOptions) + ","
|
||||||
if parts & 2:
|
if parts & 2:
|
||||||
result += stackData(parseOptions(stackOptions))
|
result += stackData(parseOptions(stackOptions))
|
||||||
if parts & 4:
|
if parts & 4:
|
||||||
result += threadsData(parseOptions(threadOptions))
|
result += threadsData(parseOptions(threadOptions))
|
||||||
|
result += "}"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def listModules():
|
def listModules():
|
||||||
result = "modules={"
|
result = "result={modules=["
|
||||||
for module in lldb.target.modules:
|
for module in lldb.target.modules:
|
||||||
result += "{file=\"%s\"" % module.file.fullpath
|
result += "{file=\"%s\"" % module.file.fullpath
|
||||||
result += ",name=\"%s\"" % module.file.basename
|
result += ",name=\"%s\"" % module.file.basename
|
||||||
@@ -176,10 +180,9 @@ def listModules():
|
|||||||
# result += ",size=\"%s\"]," % section.size
|
# result += ",size=\"%s\"]," % section.size
|
||||||
#result += "}"
|
#result += "}"
|
||||||
result += "},"
|
result += "},"
|
||||||
result += "]"
|
result += "]}"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def breakpoint_function_wrapper(baton, process, frame, bp_loc):
|
def breakpoint_function_wrapper(baton, process, frame, bp_loc):
|
||||||
result = "*stopped"
|
result = "*stopped"
|
||||||
result += ",line=\"%s\"" % frame.line_entry.line
|
result += ",line=\"%s\"" % frame.line_entry.line
|
||||||
@@ -228,7 +231,7 @@ def handleBreakpoints(stuff):
|
|||||||
target = lldb.debugger.GetTargetAtIndex(0)
|
target = lldb.debugger.GetTargetAtIndex(0)
|
||||||
#target = lldb.target
|
#target = lldb.target
|
||||||
|
|
||||||
result = "bkpts={added=["
|
result = "result={bkpts={added=["
|
||||||
|
|
||||||
for bp in todo["add"]:
|
for bp in todo["add"]:
|
||||||
bpType = bp["type"]
|
bpType = bp["type"]
|
||||||
@@ -268,30 +271,63 @@ def handleBreakpoints(stuff):
|
|||||||
bpDead = target.BreakpointDelete(int(bp["lldbid"]))
|
bpDead = target.BreakpointDelete(int(bp["lldbid"]))
|
||||||
result += "{modelid=\"%s\"}" % bp["modelid"]
|
result += "{modelid=\"%s\"}" % bp["modelid"]
|
||||||
|
|
||||||
result += "]}"
|
result += "]}}"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def doStepOver():
|
def doSomeStep(func)
|
||||||
lldb.debugger.SetAsync(False)
|
lldb.debugger.SetAsync(False)
|
||||||
lldb.thread.StepOver()
|
func()
|
||||||
lldb.debugger.SetAsync(True)
|
lldb.debugger.SetAsync(True)
|
||||||
result = "result={"
|
result = "result={"
|
||||||
result += "},"
|
result += "},"
|
||||||
result += stackData({'threadid': lldb.process.selected_thread.id})
|
result += stackData({'threadid': lldb.process.selected_thread.id})
|
||||||
result += threadsData({})
|
result += threadsData({})
|
||||||
|
result += stateData()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def doInterrupt():
|
def executeStepNext():
|
||||||
lldb.debugger.SetAsync(False)
|
return doSomeStep(lldb.thread.StepOver)
|
||||||
lldb.process.Stop()
|
|
||||||
lldb.debugger.SetAsync(True)
|
def executeStepNextI():
|
||||||
result = "result={"
|
return doSomeStep(lldb.thread.StepOver)
|
||||||
result += "}"
|
|
||||||
return result
|
def executeStep():
|
||||||
|
return doSomeStep(lldb.thread.Step)
|
||||||
|
|
||||||
|
def executeStepI():
|
||||||
|
return doSomeStep(lldb.thread.StepInstOver)
|
||||||
|
|
||||||
|
def executeStepOut():
|
||||||
|
return doSomeStep(lldb.thread.StepOut)
|
||||||
|
|
||||||
|
def executeInterrupt():
|
||||||
|
return doSomeStep(lldb.process.Stop)
|
||||||
|
|
||||||
|
def executeJumpToLine():
|
||||||
|
return doSomeStep(lldb.process.Stop)
|
||||||
|
|
||||||
|
def interruptInferior():
|
||||||
|
#lldb.process.Continue()
|
||||||
|
lldb.debugger.HandleCommand("process continue")
|
||||||
|
return "result={}"
|
||||||
|
|
||||||
|
def setupInferior(fileName):
|
||||||
|
lldb.debugger.HandleCommand("target create '%s'" % fileName)
|
||||||
|
|
||||||
|
def runEngine():
|
||||||
|
lldb.debugger.HandleCommand("process launch")
|
||||||
|
|
||||||
|
def activateFrame(frame):
|
||||||
|
lldb.debugger.HandleCommand("frame select " + frame)
|
||||||
|
|
||||||
|
def selectThread(thread):
|
||||||
|
lldb.debugger.HandleCommand("thread select " + thread)
|
||||||
|
|
||||||
|
def requestModuleSymbols(frame):
|
||||||
|
lldb.debugger.HandleCommand("target module list " + frame)
|
||||||
|
|
||||||
|
|
||||||
#lldb.debugger.HandleCommand('command script add -f ls.ls ls')
|
|
||||||
|
|
||||||
#
|
|
||||||
#SBEvent data;
|
#SBEvent data;
|
||||||
#while (!stop) {
|
#while (!stop) {
|
||||||
#if (self->m_listener.WaitForEvent(UINT32_MAX, data)) {
|
#if (self->m_listener.WaitForEvent(UINT32_MAX, data)) {
|
||||||
@@ -302,5 +338,39 @@ def doInterrupt():
|
|||||||
# // th.GetStopReasonDataAtIndex(0) should have the breakpoint id
|
# // th.GetStopReasonDataAtIndex(0) should have the breakpoint id
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
#}
|
|
||||||
#}
|
lldb.debugger.HandleCommand("setting set auto-confirm on")
|
||||||
|
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}'"
|
||||||
|
+ "\},"
|
||||||
|
@@ -109,7 +109,6 @@ LldbEngine::LldbEngine(const DebuggerStartParameters &startParameters)
|
|||||||
: DebuggerEngine(startParameters)
|
: DebuggerEngine(startParameters)
|
||||||
{
|
{
|
||||||
setObjectName(QLatin1String("LldbEngine"));
|
setObjectName(QLatin1String("LldbEngine"));
|
||||||
m_pythonAttemptedToLoad = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LldbEngine::~LldbEngine()
|
LldbEngine::~LldbEngine()
|
||||||
@@ -211,52 +210,22 @@ void LldbEngine::setupEngine()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPythonDumpers();
|
postCommand("script execfile('" +
|
||||||
postCommand("setting set auto-confirm on");
|
Core::ICore::resourcePath().toLocal8Bit() + "/dumper/bridge.py')",
|
||||||
postCommand("setting set interpreter.prompt-on-quit off");
|
CB(handleSetupEngine));
|
||||||
|
}
|
||||||
#if 0
|
|
||||||
// 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"
|
|
||||||
postCommand("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"
|
|
||||||
postCommand("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}'"
|
|
||||||
"\\},");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
void LldbEngine::handleSetupEngine(const LldbResponse &response)
|
||||||
|
{
|
||||||
|
Q_UNUSED(response);
|
||||||
notifyEngineSetupOk();
|
notifyEngineSetupOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::setupInferior()
|
void LldbEngine::setupInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
|
||||||
QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
|
QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
|
||||||
postCommand("target create " + fileName.toUtf8(), CB(handleInferiorSetup));
|
postCommand("script setupInferior('" + fileName.toUtf8() + "')",
|
||||||
|
CB(handleInferiorSetup));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleInferiorSetup(const LldbResponse &response)
|
void LldbEngine::handleInferiorSetup(const LldbResponse &response)
|
||||||
@@ -275,7 +244,7 @@ void LldbEngine::runEngine()
|
|||||||
void LldbEngine::runEngine2()
|
void LldbEngine::runEngine2()
|
||||||
{
|
{
|
||||||
showStatusMessage(tr("Running requested..."), 5000);
|
showStatusMessage(tr("Running requested..."), 5000);
|
||||||
postCommand("process launch", CB(handleRunEngine));
|
postCommand("script runEngine()", CB(handleRunEngine));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleRunEngine(const LldbResponse &response)
|
void LldbEngine::handleRunEngine(const LldbResponse &response)
|
||||||
@@ -287,87 +256,91 @@ void LldbEngine::handleRunEngine(const LldbResponse &response)
|
|||||||
void LldbEngine::interruptInferior()
|
void LldbEngine::interruptInferior()
|
||||||
{
|
{
|
||||||
showStatusMessage(tr("Interrupt requested..."), 5000);
|
showStatusMessage(tr("Interrupt requested..."), 5000);
|
||||||
//postCommand("process interrupt", CB(handleInferiorInterrupt));
|
postCommand("script interruptInferior()", CB(handleInferiorInterrupt));
|
||||||
postCommand("script doInterrupt()", CB(handleInferiorInterrupt));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleInferiorInterrupt(const LldbResponse &response)
|
void LldbEngine::handleInferiorInterrupt(const LldbResponse &response)
|
||||||
{
|
{
|
||||||
Q_UNUSED(response);
|
Q_UNUSED(response);
|
||||||
}
|
notifyInferiorStopOk();
|
||||||
|
|
||||||
void LldbEngine::handleContinue(const LldbResponse &response)
|
|
||||||
{
|
|
||||||
Q_UNUSED(response);
|
|
||||||
notifyInferiorRunOk();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeStep()
|
void LldbEngine::executeStep()
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
postCommand("script doStep()", CB(handleStepOver));
|
postCommand("script executeStep()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeStepI()
|
void LldbEngine::executeStepI()
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
postCommand("script doStepInst()", CB(handleStepOver));
|
postCommand("script executeStepI()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeStepOut()
|
void LldbEngine::executeStepOut()
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
postCommand("script doStepOut()", CB(handleStepOver));
|
postCommand("script executeStepOut()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeNext()
|
void LldbEngine::executeNext()
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
postCommand("script doStepOver()", CB(handleStepOver));
|
postCommand("script executeNext()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeNextI()
|
void LldbEngine::executeNextI()
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
postCommand("script doStepInstOver()", CB(handleStepOver));
|
postCommand("script executeStepNextI()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::continueInferior()
|
void LldbEngine::continueInferior()
|
||||||
{
|
{
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
postCommand("process continue", CB(handleContinue));
|
postCommand("script continueInferior()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleStepOver(const LldbResponse &response)
|
void LldbEngine::handleResponse(const LldbResponse &response)
|
||||||
{
|
{
|
||||||
GdbMi all = parseFromString(response.data, "result");
|
GdbMi all = parseResultFromString(response.data);
|
||||||
refreshAll(all);
|
|
||||||
notifyInferiorRunOk();
|
refreshLocals(all.findChild("data"));
|
||||||
notifyInferiorSpontaneousStop();
|
refreshStack(all.findChild("stack"));
|
||||||
|
refreshThreads(all.findChild("threads"));
|
||||||
|
refreshTypeInfo(all.findChild("typeinfo"));
|
||||||
|
refreshState(all.findChild("state"));
|
||||||
|
refreshModules(all.findChild("modules"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeRunToLine(const ContextData &data)
|
void LldbEngine::executeRunToLine(const ContextData &data)
|
||||||
{
|
{
|
||||||
Q_UNUSED(data)
|
resetLocation();
|
||||||
SDEBUG("FIXME: LldbEngine::runToLineExec()");
|
notifyInferiorRunRequested();
|
||||||
|
postCommand("script executeRunToLine(" + QByteArray::number(data.address)
|
||||||
|
+ ',' + data.fileName.toUtf8() + ')', CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeRunToFunction(const QString &functionName)
|
void LldbEngine::executeRunToFunction(const QString &functionName)
|
||||||
{
|
{
|
||||||
Q_UNUSED(functionName)
|
resetLocation();
|
||||||
XSDEBUG("FIXME: LldbEngine::runToFunctionExec()");
|
notifyInferiorRunRequested();
|
||||||
|
postCommand("script executeRunToFuntion(" + functionName.toUtf8() + ')',
|
||||||
|
CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::executeJumpToLine(const ContextData &data)
|
void LldbEngine::executeJumpToLine(const ContextData &data)
|
||||||
{
|
{
|
||||||
Q_UNUSED(data)
|
resetLocation();
|
||||||
XSDEBUG("FIXME: LldbEngine::jumpToLineExec()");
|
notifyInferiorRunRequested();
|
||||||
|
postCommand("script executeJumpToLine(" + QByteArray::number(data.address)
|
||||||
|
+ ',' + data.fileName.toUtf8() + ')', CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::activateFrame(int frameIndex)
|
void LldbEngine::activateFrame(int frameIndex)
|
||||||
@@ -376,14 +349,14 @@ void LldbEngine::activateFrame(int frameIndex)
|
|||||||
if (state() != InferiorStopOk && state() != InferiorUnrunnable)
|
if (state() != InferiorStopOk && state() != InferiorUnrunnable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
postCommand("frame select " + QByteArray::number(frameIndex),
|
postCommand("script activateFrame(" + QByteArray::number(frameIndex) + ')',
|
||||||
CB(triggerUpdateAll));
|
CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::selectThread(ThreadId threadId)
|
void LldbEngine::selectThread(ThreadId threadId)
|
||||||
{
|
{
|
||||||
postCommand("thread select " + QByteArray::number(threadId.raw()),
|
postCommand("script selectThread(" + QByteArray::number(threadId.raw()) + ')',
|
||||||
CB(triggerUpdateAll));
|
CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
||||||
@@ -550,7 +523,7 @@ void LldbEngine::updateBreakpointData(const GdbMi &bkpt, bool added)
|
|||||||
void LldbEngine::handleBreakpointsSynchronized(const LldbResponse &response)
|
void LldbEngine::handleBreakpointsSynchronized(const LldbResponse &response)
|
||||||
{
|
{
|
||||||
BreakHandler *handler = breakHandler();
|
BreakHandler *handler = breakHandler();
|
||||||
GdbMi all = parseFromString(response.data, "bkpts");
|
GdbMi all = parseResultFromString(response.data);
|
||||||
GdbMi bkpts = all.findChild("bkpts");
|
GdbMi bkpts = all.findChild("bkpts");
|
||||||
GdbMi added = bkpts.findChild("added");
|
GdbMi added = bkpts.findChild("added");
|
||||||
GdbMi changed = bkpts.findChild("changed");
|
GdbMi changed = bkpts.findChild("changed");
|
||||||
@@ -587,15 +560,13 @@ void LldbEngine::loadAllSymbols()
|
|||||||
|
|
||||||
void LldbEngine::reloadModules()
|
void LldbEngine::reloadModules()
|
||||||
{
|
{
|
||||||
postCommand("script listModules()", CB(handleListModules));
|
postCommand("script listModules()", CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleListModules(const LldbResponse &response)
|
void LldbEngine::refreshModules(const GdbMi &modules)
|
||||||
{
|
{
|
||||||
GdbMi all = parseFromString(response.data, "modules");
|
Modules mods;
|
||||||
GdbMi mods = all.findChild("modules");
|
foreach (const GdbMi &item, modules.children()) {
|
||||||
Modules modules;
|
|
||||||
foreach (const GdbMi &item, mods.children()) {
|
|
||||||
Module module;
|
Module module;
|
||||||
module.modulePath = QString::fromUtf8(item.findChild("file").data());
|
module.modulePath = QString::fromUtf8(item.findChild("file").data());
|
||||||
module.moduleName = QString::fromUtf8(item.findChild("name").data());
|
module.moduleName = QString::fromUtf8(item.findChild("name").data());
|
||||||
@@ -604,14 +575,14 @@ void LldbEngine::handleListModules(const LldbResponse &response)
|
|||||||
// item.findChild("loaded_addr").data().toULongLong(0, 0);
|
// item.findChild("loaded_addr").data().toULongLong(0, 0);
|
||||||
module.endAddress = 0; // FIXME: End address not easily available.
|
module.endAddress = 0; // FIXME: End address not easily available.
|
||||||
//modulesHandler()->updateModule(module);
|
//modulesHandler()->updateModule(module);
|
||||||
modules.append(module);
|
mods.append(module);
|
||||||
}
|
}
|
||||||
modulesHandler()->setModules(modules);
|
modulesHandler()->setModules(mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::requestModuleSymbols(const QString &moduleName)
|
void LldbEngine::requestModuleSymbols(const QString &moduleName)
|
||||||
{
|
{
|
||||||
postCommand("target module list",
|
postCommand("script requestModuleSymbols(" + moduleName.toUtf8() + ')',
|
||||||
CB(handleListSymbols), moduleName);
|
CB(handleListSymbols), moduleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,13 +600,13 @@ void LldbEngine::handleListSymbols(const LldbResponse &response)
|
|||||||
debuggerCore()->showModuleSymbols(moduleName, symbols);
|
debuggerCore()->showModuleSymbols(moduleName, symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Tooltip specific stuff
|
// Tooltip specific stuff
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
static WatchData m_toolTip;
|
static WatchData m_toolTip;
|
||||||
static QPoint m_toolTipPos;
|
static QPoint m_toolTipPos;
|
||||||
static QHash<QString, WatchData> m_toolTipCache;
|
static QHash<QString, WatchData> m_toolTipCache;
|
||||||
@@ -911,12 +882,6 @@ void LldbEngine::handleFirstCommand(const LldbResponse &response)
|
|||||||
Q_UNUSED(response);
|
Q_UNUSED(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::triggerUpdateAll(const LldbResponse &response)
|
|
||||||
{
|
|
||||||
Q_UNUSED(response);
|
|
||||||
updateAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LldbEngine::updateAll()
|
void LldbEngine::updateAll()
|
||||||
{
|
{
|
||||||
updateData(DataKind(LocalsData | StackData | ThreadData));
|
updateData(DataKind(LocalsData | StackData | ThreadData));
|
||||||
@@ -972,14 +937,14 @@ void LldbEngine::updateData(DataKind kind)
|
|||||||
+ '\'' + localsOptions + "',"
|
+ '\'' + localsOptions + "',"
|
||||||
+ '\'' + stackOptions + "',"
|
+ '\'' + stackOptions + "',"
|
||||||
+ '\'' + threadsOptions + "')",
|
+ '\'' + threadsOptions + "')",
|
||||||
CB(handleUpdateData));
|
CB(handleResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
GdbMi LldbEngine::parseFromString(QByteArray out, const QByteArray &firstTopLevel)
|
GdbMi LldbEngine::parseResultFromString(QByteArray out)
|
||||||
{
|
{
|
||||||
GdbMi all;
|
GdbMi all;
|
||||||
|
|
||||||
int pos = out.indexOf(firstTopLevel + "=");
|
int pos = out.indexOf("result=");
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
showMessage(_("UNEXPECTED LOCALS OUTPUT:" + out));
|
showMessage(_("UNEXPECTED LOCALS OUTPUT:" + out));
|
||||||
return all;
|
return all;
|
||||||
@@ -1001,36 +966,6 @@ GdbMi LldbEngine::parseFromString(QByteArray out, const QByteArray &firstTopLeve
|
|||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::handleUpdateData(const LldbResponse &response)
|
|
||||||
{
|
|
||||||
//qDebug() << " LOCALS: '" << response.data << "'";
|
|
||||||
GdbMi all = parseFromString(response.data, "data");
|
|
||||||
refreshAll(all);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LldbEngine::refreshAll(const GdbMi &all)
|
|
||||||
{
|
|
||||||
|
|
||||||
refreshLocals(all.findChild("data"));
|
|
||||||
refreshStack(all.findChild("stack"));
|
|
||||||
refreshThreads(all.findChild("threads"));
|
|
||||||
// const GdbMi typeInfo = all.findChild("typeinfo");
|
|
||||||
// if (typeInfo.type() == GdbMi::List) {
|
|
||||||
// foreach (const GdbMi &s, typeInfo.children()) {
|
|
||||||
// const GdbMi name = s.findChild("name");
|
|
||||||
// const GdbMi size = s.findChild("size");
|
|
||||||
// if (name.isValid() && size.isValid())
|
|
||||||
// m_typeInfoCache.insert(QByteArray::fromBase64(name.data()),
|
|
||||||
// TypeInfo(size.data().toUInt()));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// for (int i = 0; i != list.size(); ++i) {
|
|
||||||
// const TypeInfo ti = m_typeInfoCache.value(list.at(i).type);
|
|
||||||
// if (ti.size)
|
|
||||||
// list[i].size = ti.size;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void LldbEngine::refreshLocals(const GdbMi &vars)
|
void LldbEngine::refreshLocals(const GdbMi &vars)
|
||||||
{
|
{
|
||||||
if (!vars.isValid())
|
if (!vars.isValid())
|
||||||
@@ -1103,16 +1038,33 @@ void LldbEngine::refreshThreads(const GdbMi &threads)
|
|||||||
updateViews(); // Adjust Threads combobox.
|
updateViews(); // Adjust Threads combobox.
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::loadPythonDumpers()
|
void LldbEngine::refreshTypeInfo(const GdbMi &typeInfo)
|
||||||
{
|
{
|
||||||
if (m_pythonAttemptedToLoad)
|
if (typeInfo.type() == GdbMi::List) {
|
||||||
return;
|
// foreach (const GdbMi &s, typeInfo.children()) {
|
||||||
m_pythonAttemptedToLoad = true;
|
// const GdbMi name = s.findChild("name");
|
||||||
|
// const GdbMi size = s.findChild("size");
|
||||||
|
// if (name.isValid() && size.isValid())
|
||||||
|
// m_typeInfoCache.insert(QByteArray::fromBase64(name.data()),
|
||||||
|
// TypeInfo(size.data().toUInt()));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// for (int i = 0; i != list.size(); ++i) {
|
||||||
|
// const TypeInfo ti = m_typeInfoCache.value(list.at(i).type);
|
||||||
|
// if (ti.size)
|
||||||
|
// list[i].size = ti.size;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
const QByteArray dumperSourcePath =
|
void LldbEngine::refreshState(const GdbMi &reportedState)
|
||||||
Core::ICore::resourcePath().toLocal8Bit() + "/dumper/";
|
{
|
||||||
|
if (reportedState.isValid()) {
|
||||||
postCommand("script execfile('" + dumperSourcePath + "bridge.py')");
|
QByteArray newState = reportedState.data();
|
||||||
|
if (state() == InferiorRunRequested && newState == "running")
|
||||||
|
notifyInferiorRunOk();
|
||||||
|
else if (state() != InferiorStopOk && newState == "stopped")
|
||||||
|
notifyInferiorSpontaneousStop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LldbEngine::hasCapability(unsigned cap) const
|
bool LldbEngine::hasCapability(unsigned cap) const
|
||||||
@@ -1125,6 +1077,5 @@ DebuggerEngine *createLldbEngine(const DebuggerStartParameters &startParameters)
|
|||||||
return new LldbEngine(startParameters);
|
return new LldbEngine(startParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -110,7 +110,7 @@ private:
|
|||||||
void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
|
void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
|
||||||
|
|
||||||
void performContinuation();
|
void performContinuation();
|
||||||
void handleStepOver(const LldbResponse &response);
|
void handleResponse(const LldbResponse &response);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void outputReady(const QByteArray &data);
|
void outputReady(const QByteArray &data);
|
||||||
@@ -124,25 +124,26 @@ private:
|
|||||||
Q_SLOT void readLldbStandardOutput();
|
Q_SLOT void readLldbStandardOutput();
|
||||||
Q_SLOT void readLldbStandardError();
|
Q_SLOT void readLldbStandardError();
|
||||||
Q_SLOT void handleOutput2(const QByteArray &data);
|
Q_SLOT void handleOutput2(const QByteArray &data);
|
||||||
|
void handleSetupEngine(const LldbResponse &response);
|
||||||
void handleResponse(const QByteArray &ba);
|
void handleResponse(const QByteArray &ba);
|
||||||
void refreshAll(const GdbMi &all);
|
void refreshAll(const GdbMi &all);
|
||||||
void refreshThreads(const GdbMi &threads);
|
void refreshThreads(const GdbMi &threads);
|
||||||
void refreshStack(const GdbMi &stack);
|
void refreshStack(const GdbMi &stack);
|
||||||
void refreshLocals(const GdbMi &vars);
|
void refreshLocals(const GdbMi &vars);
|
||||||
|
void refreshTypeInfo(const GdbMi &typeInfo);
|
||||||
|
void refreshState(const GdbMi &state);
|
||||||
|
void refreshModules(const GdbMi &modules);
|
||||||
|
|
||||||
enum DataKind { LocalsData = 1, StackData = 2, ThreadData = 4 };
|
enum DataKind { LocalsData = 1, StackData = 2, ThreadData = 4 };
|
||||||
|
|
||||||
void loadPythonDumpers();
|
|
||||||
void updateAll();
|
void updateAll();
|
||||||
void updateData(DataKind kind);
|
void updateData(DataKind kind);
|
||||||
void triggerUpdateAll(const LldbResponse &response);
|
|
||||||
void handleUpdateData(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);
|
||||||
void handleRunEngine(const LldbResponse &response);
|
void handleRunEngine(const LldbResponse &response);
|
||||||
void handleInferiorInterrupt(const LldbResponse &response);
|
void handleInferiorInterrupt(const LldbResponse &response);
|
||||||
void handleContinue(const LldbResponse &response);
|
|
||||||
|
|
||||||
typedef void (LldbEngine::*LldbCommandCallback)
|
typedef void (LldbEngine::*LldbCommandCallback)
|
||||||
(const LldbResponse &response);
|
(const LldbResponse &response);
|
||||||
@@ -175,7 +176,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, const QByteArray &firstTopLevel);
|
GdbMi parseResultFromString(QByteArray out);
|
||||||
|
|
||||||
QQueue<LldbCommand> m_commands;
|
QQueue<LldbCommand> m_commands;
|
||||||
QStack<LldbCommandContinuation> m_continuations;
|
QStack<LldbCommandContinuation> m_continuations;
|
||||||
@@ -184,7 +185,6 @@ private:
|
|||||||
QString m_scriptFileName;
|
QString m_scriptFileName;
|
||||||
QProcess m_lldbProc;
|
QProcess m_lldbProc;
|
||||||
QString m_lldb;
|
QString m_lldb;
|
||||||
bool m_pythonAttemptedToLoad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
Reference in New Issue
Block a user