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)
|
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:
|
class Breakpoint:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.number = None
|
self.number = None
|
||||||
@@ -75,17 +99,6 @@ class Breakpoint:
|
|||||||
self.times = None
|
self.times = None
|
||||||
|
|
||||||
def listOfBreakpoints(d):
|
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",
|
# [bkpt={number="1",type="breakpoint",disp="keep",enabled="y",
|
||||||
#addr="0x0804da6d",func="testHidden()",file="../app.cpp",
|
#addr="0x0804da6d",func="testHidden()",file="../app.cpp",
|
||||||
#fullname="...",line="1292",times="1",original-location="\"app.cpp\":1292"},
|
#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.1 y 0x08056673 in Foo at ../app.cpp:126\n"
|
||||||
#4.2 y 0x0805678b 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"
|
#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()
|
lines.reverse()
|
||||||
bp = Breakpoint()
|
bp = Breakpoint()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
if len(line) == 0 or line.startswith(" "):
|
||||||
|
continue
|
||||||
if line[0] < '0' or line[0] > '9':
|
if line[0] < '0' or line[0] > '9':
|
||||||
continue
|
continue
|
||||||
if line.startswith("\tstop only if "):
|
if line.startswith("\tstop only if "):
|
||||||
@@ -681,6 +686,34 @@ class FrameCommand(gdb.Command):
|
|||||||
FrameCommand()
|
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();
|
setTokenBarrier();
|
||||||
setState(InferiorRunningRequested);
|
setState(InferiorRunningRequested);
|
||||||
showStatusMessage(tr("Step by instruction requested..."), 5000);
|
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())
|
if (manager()->isReverseDebugging())
|
||||||
postCommand("-reverse-stepi", RunRequest, CB(handleExecContinue));
|
postCommand("-reverse-stepi", RunRequest, CB(handleExecContinue));
|
||||||
else
|
else
|
||||||
@@ -1783,6 +1786,9 @@ void GdbEngine::nextExec()
|
|||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
setState(InferiorRunningRequested);
|
setState(InferiorRunningRequested);
|
||||||
showStatusMessage(tr("Step next requested..."), 5000);
|
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())
|
if (manager()->isReverseDebugging())
|
||||||
postCommand("-reverse-next", RunRequest, CB(handleExecNext));
|
postCommand("-reverse-next", RunRequest, CB(handleExecNext));
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ QDebug operator<<(QDebug d, MemoryRange range)
|
|||||||
MemoryRange::MemoryRange(uint f, uint t)
|
MemoryRange::MemoryRange(uint f, uint t)
|
||||||
: from(f), to(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
|
bool MemoryRange::intersects(const MemoryRange &other) const
|
||||||
@@ -167,6 +167,8 @@ void Snapshot::reset()
|
|||||||
registers[i] = 0;
|
registers[i] = 0;
|
||||||
registerValid = false;
|
registerValid = false;
|
||||||
wantedMemory = MemoryRange();
|
wantedMemory = MemoryRange();
|
||||||
|
lineFromAddress = 0;
|
||||||
|
lineToAddress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
|
void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
|
||||||
@@ -374,8 +376,18 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage(byte option)
|
|||||||
ba.reserve(17);
|
ba.reserve(17);
|
||||||
appendByte(&ba, option);
|
appendByte(&ba, option);
|
||||||
//qDebug() << "STEP ON " << hexxNumber(m_snapshot.registers[RegisterPC]);
|
//qDebug() << "STEP ON " << hexxNumber(m_snapshot.registers[RegisterPC]);
|
||||||
appendInt(&ba, m_snapshot.registers[RegisterPC]); // Start address
|
uint from = m_snapshot.lineFromAddress;
|
||||||
appendInt(&ba, m_snapshot.registers[RegisterPC]); // End address
|
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.pid);
|
||||||
appendInt(&ba, m_session.tid);
|
appendInt(&ba, m_session.tid);
|
||||||
return ba;
|
return ba;
|
||||||
@@ -678,6 +690,19 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
|
|||||||
trkReadRegistersMessage());
|
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")) {
|
else if (cmd.startsWith("Hc")) {
|
||||||
logMessage(msgGdbPacket(QLatin1String("Set thread & continue")));
|
logMessage(msgGdbPacket(QLatin1String("Set thread & continue")));
|
||||||
// Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
|
// 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("symbol-file \"" + symbolFile + "\"");
|
||||||
}
|
}
|
||||||
m_engine->postCommand("set breakpoint always-inserted on");
|
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 trust-readonly-sections"); // No difference?
|
||||||
m_engine->postCommand("set displaced-stepping on"); // No difference?
|
m_engine->postCommand("set displaced-stepping on"); // No difference?
|
||||||
m_engine->postCommand("mem 0x00400000 0x00800000 cache");
|
m_engine->postCommand("mem 0x00400000 0x00800000 cache");
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ enum CodeMode
|
|||||||
|
|
||||||
enum TargetConstants
|
enum TargetConstants
|
||||||
{
|
{
|
||||||
|
|
||||||
RegisterCount = 17,
|
RegisterCount = 17,
|
||||||
RegisterSP = 13, // Stack Pointer
|
RegisterSP = 13, // Stack Pointer
|
||||||
RegisterLR = 14, // Return address
|
RegisterLR = 14, // Return address
|
||||||
@@ -91,6 +90,8 @@ struct Snapshot
|
|||||||
void insertMemory(const MemoryRange &range, const QByteArray &ba);
|
void insertMemory(const MemoryRange &range, const QByteArray &ba);
|
||||||
|
|
||||||
uint registers[RegisterCount];
|
uint registers[RegisterCount];
|
||||||
|
uint lineFromAddress;
|
||||||
|
uint lineToAddress;
|
||||||
bool registerValid;
|
bool registerValid;
|
||||||
typedef QMap<MemoryRange, QByteArray> Memory;
|
typedef QMap<MemoryRange, QByteArray> Memory;
|
||||||
Memory memory;
|
Memory memory;
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public:
|
|||||||
int currentIndex() const { return m_currentIndex; }
|
int currentIndex() const { return m_currentIndex; }
|
||||||
StackFrame currentFrame() const;
|
StackFrame currentFrame() const;
|
||||||
int stackSize() const { return m_stackFrames.size(); }
|
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
|
// Called from StackHandler after a new stack list has been received
|
||||||
void removeAll();
|
void removeAll();
|
||||||
|
|||||||
Reference in New Issue
Block a user