forked from qt-creator/qt-creator
Debugger: Report process state and location from LLDB bridge
Change-Id: I1e65b2f75ff4ebde17f7d8506193cb47474335f6 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -76,8 +76,8 @@ if not gdbLoaded and not cdbLoaded:
|
||||
|
||||
|
||||
# One is sufficient.
|
||||
if cdbLoaded or gdbLoaded or lldbLoaded:
|
||||
failReasons = []
|
||||
#if cdbLoaded or gdbLoaded or lldbLoaded:
|
||||
# failReasons = []
|
||||
|
||||
try:
|
||||
execfile(os.path.join(currentDir, "dumper.py"))
|
||||
|
@@ -860,7 +860,7 @@ def stripForFormat(typeName):
|
||||
qqStripForFormat[typeName] = stripped
|
||||
return stripped
|
||||
|
||||
def bbsetup(args):
|
||||
def bbsetup(args = ''):
|
||||
typeCache = {}
|
||||
module = sys.modules[__name__]
|
||||
for key, value in module.__dict__.items():
|
||||
|
@@ -121,8 +121,19 @@ def threadsData(options):
|
||||
result += "],current-thread-id=\"%s\"}" % lldb.process.selected_thread.id
|
||||
return result
|
||||
|
||||
# See lldb.StateType
|
||||
stateNames = ["invalid", "unloaded", "connected", "attaching", "launching", "stopped",
|
||||
"running", "stepping", "crashed", "detached", "exited", "suspended" ]
|
||||
|
||||
def stateData(options):
|
||||
result = "state={},"
|
||||
state = lldb.process.GetState()
|
||||
return "state=\"%s\"," % stateNames[state]
|
||||
|
||||
def locationData(options):
|
||||
thread = lldb.process.GetSelectedThread()
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
return "location={file=\"%s\",line=\"%s\",addr=\"%s\"}," \
|
||||
% (frame.line_entry.file, frame.line_entry.line, frame.pc)
|
||||
|
||||
def stackData(options):
|
||||
try:
|
||||
@@ -163,6 +174,8 @@ def updateData(parts, localsOptions, stackOptions, threadOptions):
|
||||
result += stackData(parseOptions(stackOptions))
|
||||
if parts & 4:
|
||||
result += threadsData(parseOptions(threadOptions))
|
||||
result += stateData({})
|
||||
result += locationData({})
|
||||
result += "}"
|
||||
return result
|
||||
|
||||
@@ -274,42 +287,57 @@ def handleBreakpoints(stuff):
|
||||
result += "]}}"
|
||||
return result
|
||||
|
||||
def doSomeStep(func)
|
||||
def doSync(func):
|
||||
lldb.debugger.SetAsync(False)
|
||||
func()
|
||||
lldb.debugger.SetAsync(True)
|
||||
|
||||
def createReport():
|
||||
result = "result={"
|
||||
result += "},"
|
||||
result += stackData({'threadid': lldb.process.selected_thread.id})
|
||||
result += threadsData({})
|
||||
result += stateData()
|
||||
result += stateData({})
|
||||
result += locationData({})
|
||||
result += "}"
|
||||
return result
|
||||
|
||||
def executeStepNext():
|
||||
return doSomeStep(lldb.thread.StepOver)
|
||||
def executeNext():
|
||||
doSync(lldb.thread.StepOver)
|
||||
return createReport()
|
||||
|
||||
def executeStepNextI():
|
||||
return doSomeStep(lldb.thread.StepOver)
|
||||
def executeNextI():
|
||||
doSync(lldb.thread.StepOver)
|
||||
return createReport()
|
||||
|
||||
def executeStep():
|
||||
return doSomeStep(lldb.thread.Step)
|
||||
doSync(lldb.thread.Step)
|
||||
return createReport()
|
||||
|
||||
def executeStepI():
|
||||
return doSomeStep(lldb.thread.StepInstOver)
|
||||
doSync(lldb.thread.StepInstOver)
|
||||
return createReport()
|
||||
|
||||
def executeStepOut():
|
||||
return doSomeStep(lldb.thread.StepOut)
|
||||
doSync(lldb.thread.StepOut)
|
||||
return createReport()
|
||||
|
||||
def executeInterrupt():
|
||||
return doSomeStep(lldb.process.Stop)
|
||||
def executeRunToLine():
|
||||
return "result={error={msg='Not implemented'}}"
|
||||
|
||||
def executeJumpToLine():
|
||||
return doSomeStep(lldb.process.Stop)
|
||||
return "result={error={msg='Not implemented'}}"
|
||||
|
||||
def continueInferior():
|
||||
#lldb.debugger.HandleCommand("process continue")
|
||||
lldb.process.Continue()
|
||||
return "result={state='running'}"
|
||||
|
||||
def interruptInferior():
|
||||
#lldb.process.Continue()
|
||||
lldb.debugger.HandleCommand("process continue")
|
||||
return "result={}"
|
||||
lldb.debugger.SetAsync(False)
|
||||
lldb.process.Stop()
|
||||
#lldb.process.SendAsyncInterrupt()
|
||||
lldb.debugger.SetAsync(True)
|
||||
return createReport()
|
||||
|
||||
def setupInferior(fileName):
|
||||
lldb.debugger.HandleCommand("target create '%s'" % fileName)
|
||||
@@ -373,4 +401,4 @@ if False:
|
||||
+ "pcoffset='${function.pc-offset}',"
|
||||
+ "stopreason='${thread.stop-reason}'"
|
||||
#+ "returnvalue='${thread.return-value}'"
|
||||
+ "\},"
|
||||
+ "\},")
|
||||
|
@@ -316,6 +316,7 @@ void LldbEngine::handleResponse(const LldbResponse &response)
|
||||
refreshThreads(all.findChild("threads"));
|
||||
refreshTypeInfo(all.findChild("typeinfo"));
|
||||
refreshState(all.findChild("state"));
|
||||
refreshLocation(all.findChild("location"));
|
||||
refreshModules(all.findChild("modules"));
|
||||
}
|
||||
|
||||
@@ -783,7 +784,7 @@ static bool isEatable(char c)
|
||||
void LldbEngine::readLldbStandardOutput()
|
||||
{
|
||||
QByteArray out = m_lldbProc.readAllStandardOutput();
|
||||
showMessage(_("Lldb stdout: " + out));
|
||||
//showMessage(_("Lldb stdout: " + out));
|
||||
qDebug("\nLLDB RAW STDOUT: '%s'", quoteUnprintable(out).constData());
|
||||
// Remove embedded backspace characters
|
||||
int j = 1;
|
||||
@@ -843,7 +844,7 @@ void LldbEngine::readLldbStandardOutput()
|
||||
if (m_inbuffer.mid(pos1 + 1).startsWith("stopped")) {
|
||||
m_inbuffer.clear();
|
||||
notifyInferiorSpontaneousStop();
|
||||
gotoLocation(stackHandler()->currentFrame());
|
||||
//gotoLocation(stackHandler()->currentFrame());
|
||||
updateAll();
|
||||
} else if (m_inbuffer.mid(pos1 + 1).startsWith("exited")) {
|
||||
m_inbuffer.clear();
|
||||
@@ -859,7 +860,7 @@ void LldbEngine::handleOutput2(const QByteArray &data)
|
||||
{
|
||||
LldbResponse response;
|
||||
response.data = data;
|
||||
showMessage(_(data));
|
||||
//showMessage(_(data));
|
||||
QTC_ASSERT(!m_commands.isEmpty(), qDebug() << "RESPONSE: " << data; return);
|
||||
LldbCommand cmd = m_commands.dequeue();
|
||||
// FIXME: Find a way to tell LLDB to no echo input.
|
||||
@@ -962,7 +963,7 @@ GdbMi LldbEngine::parseResultFromString(QByteArray out)
|
||||
else
|
||||
showMessage(_("JUNK AT END OF RESPONSE: " + out));
|
||||
|
||||
all.fromStringMultiple(out);
|
||||
all.fromString(out);
|
||||
return all;
|
||||
}
|
||||
|
||||
@@ -1067,6 +1068,15 @@ void LldbEngine::refreshState(const GdbMi &reportedState)
|
||||
}
|
||||
}
|
||||
|
||||
void LldbEngine::refreshLocation(const GdbMi &reportedLocation)
|
||||
{
|
||||
if (reportedLocation.isValid()) {
|
||||
QByteArray file = reportedLocation.findChild("file").data();
|
||||
int line = reportedLocation.findChild("line").data().toInt();
|
||||
gotoLocation(Location(QString::fromUtf8(file), line));
|
||||
}
|
||||
}
|
||||
|
||||
bool LldbEngine::hasCapability(unsigned cap) const
|
||||
{
|
||||
return cap & (ReloadModuleCapability|BreakConditionCapability);
|
||||
|
@@ -132,6 +132,7 @@ private:
|
||||
void refreshLocals(const GdbMi &vars);
|
||||
void refreshTypeInfo(const GdbMi &typeInfo);
|
||||
void refreshState(const GdbMi &state);
|
||||
void refreshLocation(const GdbMi &location);
|
||||
void refreshModules(const GdbMi &modules);
|
||||
|
||||
enum DataKind { LocalsData = 1, StackData = 2, ThreadData = 4 };
|
||||
|
Reference in New Issue
Block a user