Commit 8931a14a authored by hjk's avatar hjk
Browse files

Debugger: Select topmost frame with usable data also with LLDB



Task-number: QTCREATORBUG-11597
Change-Id: I5d95c9172e90b82f5671427283cf46e924456c4c
Reviewed-by: default avatarChristian Stenger <christian.stenger@digia.com>
parent fed6b8bd
......@@ -831,16 +831,10 @@ class Dumper(DumperBase):
if not thread:
self.report('msg="No thread"')
return
frame = thread.GetSelectedFrame()
if frame:
frameId = frame.GetFrameID()
else:
frameId = 0;
(n, isLimited) = (limit, True) if limit > 0 else (thread.GetNumFrames(), False)
result = 'stack={current-frame="%s"' % frameId
result += ',current-thread="%s"' % thread.GetThreadID()
result = 'stack={current-thread="%s"' % thread.GetThreadID()
result += ',frames=['
for i in xrange(n):
frame = thread.GetFrameAtIndex(i)
......@@ -849,14 +843,12 @@ class Dumper(DumperBase):
break
lineEntry = frame.GetLineEntry()
line = lineEntry.GetLine()
usable = line != 0
result += '{pc="0x%x"' % frame.GetPC()
result += ',level="%d"' % frame.idx
result += ',addr="0x%x"' % frame.GetPCAddress().GetLoadAddress(self.target)
result += ',func="%s"' % frame.GetFunctionName()
result += ',line="%d"' % line
result += ',fullname="%s"' % fileName(lineEntry.file)
result += ',usable="%d"' % usable
result += ',file="%s"},' % fileName(lineEntry.file)
result += ']'
result += ',hasmore="%d"' % isLimited
......@@ -864,6 +856,20 @@ class Dumper(DumperBase):
result += '}'
self.report(result)
def reportStackPosition(self):
thread = self.currentThread()
if not thread:
self.report('msg="No thread"')
return
frame = thread.GetSelectedFrame()
if frame:
self.report('stack-position={id="%s"}' % frame.GetFrameID())
else:
self.report('stack-position={id="-1"}')
def reportStackTop(self):
self.report('stack-top={}')
def putBetterType(self, type):
try:
self.currentType = type.GetName()
......@@ -1196,8 +1202,8 @@ class Dumper(DumperBase):
state = self.process.GetState()
if state == lldb.eStateStopped:
self.reportStack()
self.reportStackPosition()
self.reportThreads()
self.reportLocation()
self.reportVariables()
def reportRegisters(self, _ = None):
......@@ -1284,10 +1290,8 @@ class Dumper(DumperBase):
stoppedThread = self.firstStoppedThread()
if stoppedThread:
self.process.SetSelectedThread(stoppedThread)
usableFrame = self.firstUsableFrame(stoppedThread)
if usableFrame:
stoppedThread.SetSelectedFrame(usableFrame)
self.reportStack({'stacklimit': 20})
self.reportStackTop()
self.reportThreads()
self.reportLocation()
self.reportVariables()
......@@ -1564,9 +1568,7 @@ class Dumper(DumperBase):
self.currentThread().SetSelectedFrame(args['index'])
state = self.process.GetState()
if state == lldb.eStateStopped:
self.reportStack(args)
self.reportThreads()
self.reportLocation()
self.reportStackPosition()
self.reportVariables()
def selectThread(self, args):
......@@ -1601,19 +1603,30 @@ class Dumper(DumperBase):
self.reportVariables(args)
def disassemble(self, args):
frame = self.currentFrame();
function = frame.GetFunction()
name = function.GetName()
functionName = args.get('function', '')
flavor = args.get('flavor', '')
function = None
if len(functionName):
functions = self.target.FindFunctions(functionName).functions
if len(functions):
function = functions[0]
if function:
base = function.GetStartAddress().GetLoadAddress(self.target)
instructions = function.GetInstructions(self.target)
else:
base = args.get('address', 0)
addr = lldb.SBAddress(base, self.target)
instructions = self.target.ReadInstructions(addr, 100)
result = 'disassembly={cookie="%s",' % args['cookie']
result += ',lines=['
base = function.GetStartAddress().GetLoadAddress(self.target)
for insn in function.GetInstructions(self.target):
for insn in instructions:
comment = insn.GetComment(self.target)
addr = insn.GetAddress().GetLoadAddress(self.target)
result += '{address="%s"' % addr
result += ',inst="%s %s"' % (insn.GetMnemonic(self.target),
insn.GetOperands(self.target))
result += ',func_name="%s"' % name
result += ',func_name="%s"' % functionName
if comment:
result += ',comment="%s"' % comment
result += ',offset="%s"},' % (addr - base)
......
......@@ -401,6 +401,10 @@ void LldbEngine::handleResponse(const QByteArray &response)
refreshLocals(item);
else if (name == "stack")
refreshStack(item);
else if (name == "stack-position")
refreshStackPosition(item);
else if (name == "stack-top")
refreshStackTop(item);
else if (name == "registers")
refreshRegisters(item);
else if (name == "threads")
......@@ -1083,8 +1087,6 @@ void LldbEngine::refreshLocals(const GdbMi &vars)
void LldbEngine::refreshStack(const GdbMi &stack)
{
//if (!partial)
// emit stackFrameCompleted();
StackHandler *handler = stackHandler();
StackFrames frames;
foreach (const GdbMi &item, stack["frames"].children()) {
......@@ -1101,9 +1103,25 @@ void LldbEngine::refreshStack(const GdbMi &stack)
bool canExpand = stack["hasmore"].toInt();
debuggerCore()->action(ExpandStack)->setEnabled(canExpand);
handler->setFrames(frames, canExpand);
}
void LldbEngine::refreshStackPosition(const GdbMi &position)
{
setStackPosition(position["id"].toInt());
}
void LldbEngine::refreshStackTop(const GdbMi &)
{
setStackPosition(stackHandler()->firstUsableIndex());
}
int index = stack["current-frame"].toInt();
void LldbEngine::setStackPosition(int index)
{
StackHandler *handler = stackHandler();
handler->setFrames(handler->frames());
handler->setCurrentIndex(index);
if (index >= 0 && index < handler->stackSize())
gotoLocation(handler->frameAt(index));
}
void LldbEngine::refreshRegisters(const GdbMi &registers)
......@@ -1221,7 +1239,13 @@ void LldbEngine::fetchDisassembler(DisassemblerAgent *agent)
id = ++m_lastAgentId;
m_disassemblerAgents.insert(p, id);
}
runCommand(Command("disassemble").arg("cookie", id));
const Location &loc = agent->location();
Command cmd("disassemble");
cmd.arg("cookie", id);
cmd.arg("address", loc.address());
cmd.arg("function", loc.functionName());
cmd.arg("flavor", debuggerCore()->boolSetting(IntelFlavor) ? "intel" : "att");
runCommand(cmd);
}
......@@ -1234,10 +1258,11 @@ void LldbEngine::fetchMemory(MemoryAgent *agent, QObject *editorToken,
m_memoryAgents.insert(agent, id);
}
m_memoryAgentTokens.insert(id, editorToken);
runCommand(Command("fetchMemory")
.arg("address", addr)
.arg("length", length)
.arg("cookie", id));
Command cmd("fetchMemory");
cmd.arg("address", addr);
cmd.arg("length", length);
cmd.arg("cookie", id);
runCommand(cmd);
}
void LldbEngine::changeMemory(MemoryAgent *agent, QObject *editorToken,
......@@ -1249,10 +1274,11 @@ void LldbEngine::changeMemory(MemoryAgent *agent, QObject *editorToken,
m_memoryAgents.insert(agent, id);
m_memoryAgentTokens.insert(id, editorToken);
}
runCommand(Command("writeMemory")
.arg("address", addr)
.arg("data", data.toHex())
.arg("cookie", id));
Command cmd("writeMemory");
cmd.arg("address", addr);
cmd.arg("data", data.toHex());
cmd.arg("cookie", id);
runCommand(cmd);
}
void LldbEngine::setRegisterValue(int regnr, const QString &value)
......
......@@ -166,6 +166,9 @@ private:
void refreshAll(const GdbMi &all);
void refreshThreads(const GdbMi &threads);
void refreshStack(const GdbMi &stack);
void refreshStackPosition(const GdbMi &position);
void refreshStackTop(const GdbMi &position);
void setStackPosition(int index);
void refreshRegisters(const GdbMi &registers);
void refreshLocals(const GdbMi &vars);
void refreshTypeInfo(const GdbMi &typeInfo);
......
......@@ -219,6 +219,16 @@ void StackHandler::prependFrames(const StackFrames &frames)
emit stackChanged();
}
int StackHandler::firstUsableIndex() const
{
if (!debuggerCore()->boolSetting(OperateByInstruction)) {
for (int i = 0, n = m_stackFrames.size(); i != n; ++i)
if (m_stackFrames.at(i).isUsable())
return i;
}
return 0;
}
const StackFrames &StackHandler::frames() const
{
return m_stackFrames;
......
......@@ -71,6 +71,7 @@ public:
const StackFrames &frames() const;
void setCurrentIndex(int index);
int currentIndex() const { return m_currentIndex; }
int firstUsableIndex() const;
StackFrame currentFrame() const;
const StackFrame &frameAt(int index) const { return m_stackFrames.at(index); }
int stackSize() const { return m_stackFrames.size(); }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment