forked from qt-creator/qt-creator
debugger: start using TRK's 'multi instruction step' facility
This commit is contained in:
@@ -63,6 +63,30 @@ def parseAndEvaluate(exp):
|
||||
return gdb.history(0)
|
||||
|
||||
|
||||
def catchCliOutput(command):
|
||||
file = tempfile.mkstemp(prefix="gdbpy_")
|
||||
filename = file[1]
|
||||
gdb.execute("set logging off")
|
||||
gdb.execute("set logging redirect off")
|
||||
gdb.execute("set logging file %s" % filename)
|
||||
gdb.execute("set logging redirect on")
|
||||
gdb.execute("set logging on")
|
||||
gdb.execute(command)
|
||||
gdb.execute("set logging off")
|
||||
gdb.execute("set logging redirect off")
|
||||
gdb.execute("set logging file \"\"")
|
||||
file = open(filename, "r")
|
||||
lines = []
|
||||
for line in file:
|
||||
lines.append(line)
|
||||
file.close()
|
||||
try: # files may still be locked by gdb on Windows
|
||||
os.remove(filename)
|
||||
except:
|
||||
pass
|
||||
return lines
|
||||
|
||||
|
||||
class Breakpoint:
|
||||
def __init__(self):
|
||||
self.number = None
|
||||
@@ -75,17 +99,6 @@ class Breakpoint:
|
||||
self.times = None
|
||||
|
||||
def listOfBreakpoints(d):
|
||||
file = tempfile.mkstemp(prefix="gdbpy_")
|
||||
filename = file[1]
|
||||
gdb.execute("set logging off")
|
||||
gdb.execute("set logging redirect off")
|
||||
gdb.execute("set logging file %s" % filename)
|
||||
gdb.execute("set logging redirect on")
|
||||
gdb.execute("set logging on")
|
||||
gdb.execute("info break")
|
||||
gdb.execute("set logging off")
|
||||
gdb.execute("set logging redirect off")
|
||||
|
||||
# [bkpt={number="1",type="breakpoint",disp="keep",enabled="y",
|
||||
#addr="0x0804da6d",func="testHidden()",file="../app.cpp",
|
||||
#fullname="...",line="1292",times="1",original-location="\"app.cpp\":1292"},
|
||||
@@ -98,21 +111,13 @@ def listOfBreakpoints(d):
|
||||
#4.1 y 0x08056673 in Foo at ../app.cpp:126\n"
|
||||
#4.2 y 0x0805678b in Foo at ../app.cpp:126\n"
|
||||
#5 hw watchpoint keep y &main\n"
|
||||
lines = catchCliOutput("info break")
|
||||
|
||||
file = open(filename, "r")
|
||||
lines = []
|
||||
for line in file:
|
||||
if len(line) == 0 or line.startswith(" "):
|
||||
continue
|
||||
lines.append(line)
|
||||
file.close()
|
||||
try: # files may still be locked by gdb on Windows
|
||||
os.remove(filename)
|
||||
except:
|
||||
pass
|
||||
lines.reverse()
|
||||
bp = Breakpoint()
|
||||
for line in lines:
|
||||
if len(line) == 0 or line.startswith(" "):
|
||||
continue
|
||||
if line[0] < '0' or line[0] > '9':
|
||||
continue
|
||||
if line.startswith("\tstop only if "):
|
||||
@@ -681,6 +686,34 @@ class FrameCommand(gdb.Command):
|
||||
FrameCommand()
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Step Command
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
|
||||
class SalCommand(gdb.Command):
|
||||
"""Do fancy stuff."""
|
||||
|
||||
def __init__(self):
|
||||
super(SalCommand, self).__init__("sal", gdb.COMMAND_OBSCURE)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
lines = catchCliOutput("info line *" + arg)
|
||||
fromAddr = "0x0"
|
||||
toAddr = "0x0"
|
||||
for line in lines:
|
||||
pos0from = line.find(" starts at address") + 19
|
||||
pos1from = line.find(" ", pos0from)
|
||||
pos0to = line.find(" ends at", pos1from) + 9
|
||||
pos1to = line.find(" ", pos0to)
|
||||
if pos1to > 0:
|
||||
fromAddr = line[pos0from : pos1from]
|
||||
toAddr = line[pos0to : pos1to]
|
||||
gdb.execute("maint packet sal%s,%s" % (fromAddr, toAddr))
|
||||
|
||||
SalCommand()
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
|
||||
@@ -1762,6 +1762,9 @@ void GdbEngine::stepIExec()
|
||||
setTokenBarrier();
|
||||
setState(InferiorRunningRequested);
|
||||
showStatusMessage(tr("Step by instruction requested..."), 5000);
|
||||
StackHandler *stackHandler = manager()->stackHandler();
|
||||
if (m_gdbAdapter->isTrkAdapter() && stackHandler->stackSize() > 0)
|
||||
postCommand("sal " + stackHandler->topAddress().toLatin1());
|
||||
if (manager()->isReverseDebugging())
|
||||
postCommand("-reverse-stepi", RunRequest, CB(handleExecContinue));
|
||||
else
|
||||
@@ -1783,6 +1786,9 @@ void GdbEngine::nextExec()
|
||||
setTokenBarrier();
|
||||
setState(InferiorRunningRequested);
|
||||
showStatusMessage(tr("Step next requested..."), 5000);
|
||||
StackHandler *stackHandler = manager()->stackHandler();
|
||||
if (m_gdbAdapter->isTrkAdapter() && stackHandler->stackSize() > 0)
|
||||
postCommand("sal " + stackHandler->topAddress().toLatin1());
|
||||
if (manager()->isReverseDebugging())
|
||||
postCommand("-reverse-next", RunRequest, CB(handleExecNext));
|
||||
else
|
||||
|
||||
@@ -122,7 +122,7 @@ QDebug operator<<(QDebug d, MemoryRange range)
|
||||
MemoryRange::MemoryRange(uint f, uint t)
|
||||
: from(f), to(t)
|
||||
{
|
||||
QTC_ASSERT(f <= t, /**/);
|
||||
QTC_ASSERT(f <= t, qDebug() << "F: " << f << " T: " << t);
|
||||
}
|
||||
|
||||
bool MemoryRange::intersects(const MemoryRange &other) const
|
||||
@@ -167,6 +167,8 @@ void Snapshot::reset()
|
||||
registers[i] = 0;
|
||||
registerValid = false;
|
||||
wantedMemory = MemoryRange();
|
||||
lineFromAddress = 0;
|
||||
lineToAddress = 0;
|
||||
}
|
||||
|
||||
void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
|
||||
@@ -374,8 +376,18 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage(byte option)
|
||||
ba.reserve(17);
|
||||
appendByte(&ba, option);
|
||||
//qDebug() << "STEP ON " << hexxNumber(m_snapshot.registers[RegisterPC]);
|
||||
appendInt(&ba, m_snapshot.registers[RegisterPC]); // Start address
|
||||
appendInt(&ba, m_snapshot.registers[RegisterPC]); // End address
|
||||
uint from = m_snapshot.lineFromAddress;
|
||||
uint to = m_snapshot.lineToAddress;
|
||||
uint pc = m_snapshot.registers[RegisterPC];
|
||||
if (from <= pc && pc <= to) {
|
||||
qDebug() << "STEP IN " << hexxNumber(from) << hexxNumber(to)
|
||||
<< "INSTEAD OF " << hexxNumber(pc);
|
||||
} else {
|
||||
from = pc;
|
||||
to = pc;
|
||||
}
|
||||
appendInt(&ba, from); // Start address
|
||||
appendInt(&ba, to); // End address
|
||||
appendInt(&ba, m_session.pid);
|
||||
appendInt(&ba, m_session.tid);
|
||||
return ba;
|
||||
@@ -678,6 +690,19 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
|
||||
trkReadRegistersMessage());
|
||||
}
|
||||
|
||||
else if (cmd.startsWith("sal")) {
|
||||
// Receive address range for current line for future use when stepping.
|
||||
sendGdbServerAck();
|
||||
int pos = cmd.indexOf(',');
|
||||
//qDebug() << "SAL: " << cmd << cmd.mid(3, pos - 3) << cmd.mid(pos + 1);
|
||||
bool ok = false;
|
||||
m_snapshot.lineFromAddress = cmd.mid(3, pos - 3).toUInt(0, 16);
|
||||
m_snapshot.lineToAddress = cmd.mid(pos + 1).toUInt(0, 16);
|
||||
//qDebug() << "SAL: " << hexxNumber(m_snapshot.lineFromAddress)
|
||||
// << hexxNumber(m_snapshot.lineToAddress);
|
||||
sendGdbServerMessage("", "Stepping range received");
|
||||
}
|
||||
|
||||
else if (cmd.startsWith("Hc")) {
|
||||
logMessage(msgGdbPacket(QLatin1String("Set thread & continue")));
|
||||
// Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
|
||||
@@ -1823,6 +1848,7 @@ void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
|
||||
m_engine->postCommand("symbol-file \"" + symbolFile + "\"");
|
||||
}
|
||||
m_engine->postCommand("set breakpoint always-inserted on");
|
||||
m_engine->postCommand("set breakpoint auto-hw off");
|
||||
m_engine->postCommand("set trust-readonly-sections"); // No difference?
|
||||
m_engine->postCommand("set displaced-stepping on"); // No difference?
|
||||
m_engine->postCommand("mem 0x00400000 0x00800000 cache");
|
||||
|
||||
@@ -59,7 +59,6 @@ enum CodeMode
|
||||
|
||||
enum TargetConstants
|
||||
{
|
||||
|
||||
RegisterCount = 17,
|
||||
RegisterSP = 13, // Stack Pointer
|
||||
RegisterLR = 14, // Return address
|
||||
@@ -91,6 +90,8 @@ struct Snapshot
|
||||
void insertMemory(const MemoryRange &range, const QByteArray &ba);
|
||||
|
||||
uint registers[RegisterCount];
|
||||
uint lineFromAddress;
|
||||
uint lineToAddress;
|
||||
bool registerValid;
|
||||
typedef QMap<MemoryRange, QByteArray> Memory;
|
||||
Memory memory;
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
int currentIndex() const { return m_currentIndex; }
|
||||
StackFrame currentFrame() const;
|
||||
int stackSize() const { return m_stackFrames.size(); }
|
||||
QString topAddress() const { return m_stackFrames.at(0).address; }
|
||||
|
||||
// Called from StackHandler after a new stack list has been received
|
||||
void removeAll();
|
||||
|
||||
Reference in New Issue
Block a user