highlight PC line while debugging (#541)

* highlight PC line while debugging

* highlight PC correctly
This commit is contained in:
fcasal 2018-06-22 16:57:15 +01:00 committed by xarkes
parent 1f49440c02
commit 837ffef20f
7 changed files with 85 additions and 11 deletions

View File

@ -751,6 +751,18 @@ QString CutterCore::getRegisterName(QString registerRole)
return cmd("drn " + registerRole).trimmed();
}
RVA CutterCore::getProgramCounterValue()
{
bool ok;
if (currentlyDebugging) {
RVA addr = cmd("dr?`drn PC`").toULongLong(&ok, 16);
if (ok) {
return addr;
}
}
return RVA_INVALID;
}
void CutterCore::setRegister(QString regName, QString regValue)
{
cmd("dr " + regName + "=" + regValue);
@ -774,11 +786,13 @@ void CutterCore::stopDebug()
{
// @TODO should first obtain correct signal to send.
// Also, we do a ds since otherwise the process does not die.
if (currentlyDebugging) {
cmd("dk 9; ds; e cfg.debug = false; oo");
seek(offsetPriorDebugging);
emit changeDefinedView();
currentlyDebugging = false;
}
}
void CutterCore::continueDebug()
{
@ -795,7 +809,7 @@ void CutterCore::continueUntilDebug(QString offset)
void CutterCore::continueUntilCall()
{
cmd("dcc");
QString programCounterValue = cmd("dr?`drn pc`").trimmed();
QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue);
emit registersChanged();
}
@ -803,7 +817,7 @@ void CutterCore::continueUntilCall()
void CutterCore::continueUntilSyscall()
{
cmd("dcs");
QString programCounterValue = cmd("dr?`drn pc`").trimmed();
QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue);
emit registersChanged();
}
@ -811,7 +825,7 @@ void CutterCore::continueUntilSyscall()
void CutterCore::stepDebug()
{
cmd("ds");
QString programCounterValue = cmd("dr?`drn pc`").trimmed();
QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue);
emit registersChanged();
}
@ -819,7 +833,7 @@ void CutterCore::stepDebug()
void CutterCore::stepOverDebug()
{
cmd("dso");
QString programCounterValue = cmd("dr?`drn pc`").trimmed();
QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue);
emit registersChanged();
}

View File

@ -475,6 +475,7 @@ public:
QJsonDocument getRegistersInfo();
QJsonDocument getRegisterValues();
QString getRegisterName(QString registerRole);
RVA getProgramCounterValue();
void setRegister(QString regName, QString regValue);
QJsonDocument getStack(int size = 0x40);
QJsonDocument getBacktrace();
@ -494,6 +495,7 @@ public:
QString getActiveDebugPlugin();
QStringList getDebugPlugins();
void setDebugPlugin(QString plugin);
bool currentlyDebugging = false;
RVA getOffsetJump(RVA addr);
QString getDecompiledCode(RVA addr);

View File

@ -422,12 +422,14 @@ void MainWindow::closeEvent(QCloseEvent *event)
tr("Do you really want to exit?\nSave your project before closing!"),
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
if (ret == QMessageBox::Save) {
if (saveProject(true)) {
if (saveProject(true) && !Core()->currentlyDebugging) {
saveSettings();
}
QMainWindow::closeEvent(event);
} else if (ret == QMessageBox::Discard) {
if (!Core()->currentlyDebugging) {
saveSettings();
}
QMainWindow::closeEvent(event);
} else {
event->ignore();

View File

@ -119,6 +119,8 @@ void Configuration::loadDefaultTheme()
setColor("gui.border", QColor(0, 0, 0));
setColor("highlight", QColor(210, 210, 255));
setColor("highlightWord", QColor(210, 210, 255));
// RIP line selection in debug
setColor("highlightPC", QColor(214, 255, 210));
// Windows background
setColor("gui.background", QColor(255, 255, 255));
setColor("gui.disass_selected", QColor(255, 255, 255));
@ -171,6 +173,8 @@ void Configuration::loadBaseDark()
setColor("gui.navbar.str", QColor(69, 104, 229));
setColor("gui.navbar.sym", QColor(229, 150, 69));
setColor("gui.navbar.empty", QColor(100, 100, 100));
// RIP line selection in debug
setColor("highlightPC", QColor(87, 26, 7));
}
void Configuration::loadDarkTheme()

View File

@ -335,15 +335,20 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
// Render node
DisassemblyBlock &db = disassembly_blocks[block.entry];
bool block_selected = false;
bool PCInBlock = false;
RVA selected_instruction = RVA_INVALID;
// Figure out if the current block is selected
for (const Instr &instr : db.instrs) {
RVA addr = seekable->getOffset();
RVA PCAddr = Core()->getProgramCounterValue();
for (const Instr &instr : db.instrs) {
if ((instr.addr <= addr) && (addr <= instr.addr + instr.size)) {
block_selected = true;
selected_instruction = instr.addr;
}
if ((instr.addr <= PCAddr) && (PCAddr <= instr.addr + instr.size)) {
PCInBlock = true;
}
// TODO: L219
}
@ -370,6 +375,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
block.width, block.height);
// Draw different background for selected instruction
bool paintedSelected = false;
if (selected_instruction != RVA_INVALID) {
int y = block.y + (2 * charWidth) + (db.header_text.lines.size() * charHeight);
for (Instr &instr : db.instrs) {
@ -379,9 +385,11 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
if (selected && traceCount) {
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth),
int(instr.text.lines.size()) * charHeight), disassemblyTracedSelectionColor);
paintedSelected = true;
} else if (selected) {
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth),
int(instr.text.lines.size()) * charHeight), disassemblySelectionColor);
paintedSelected = true;
} else if (traceCount) {
// Color depending on how often a sequence of code is executed
int exponent = 1;
@ -398,11 +406,28 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
QColor(disassemblyTracedColor.red(),
disassemblyTracedColor.green(),
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
paintedSelected = true;
}
if (paintedSelected) {
break;
}
y += int(instr.text.lines.size()) * charHeight;
}
}
// highlight program counter
if (PCInBlock) {
int y = block.y + (2 * charWidth) + (db.header_text.lines.size() * charHeight);
for (Instr &instr : db.instrs) {
auto PC = instr.addr == PCAddr;
if (PC) {
p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth),
int(instr.text.lines.size()) * charHeight), PCSelectionColor);
break;
}
y += int(instr.text.lines.size()) * charHeight;
}
}
// Render node text
auto x = block.x + (2 * charWidth);
@ -504,6 +529,7 @@ void DisassemblerGraphView::colorsUpdatedSlot()
graphNodeColor = ConfigColor("gui.border");
backgroundColor = ConfigColor("gui.background");
disassemblySelectionColor = ConfigColor("highlight");
PCSelectionColor = ConfigColor("highlightPC");
jmpColor = ConfigColor("graph.trufae");
brtrueColor = ConfigColor("graph.true");

View File

@ -201,6 +201,7 @@ private:
QColor disassemblyBackgroundColor;
QColor disassemblySelectedBackgroundColor;
QColor disassemblySelectionColor;
QColor PCSelectionColor;
QColor disassemblyTracedColor;
QColor disassemblyTracedSelectionColor;
QColor jmpColor;

View File

@ -310,6 +310,7 @@ void DisassemblyWidget::highlightCurrentLine()
QList<QTextEdit::ExtraSelection> extraSelections;
QColor highlightColor = ConfigColor("highlight");
QColor highlightPCColor = ConfigColor("highlightPC");
QColor highlightWordColor = ConfigColor("highlightWord");
highlightWordColor.setAlpha(128);
QColor highlightWordCurrentLineColor = ConfigColor("gui.background");
@ -357,6 +358,30 @@ void DisassemblyWidget::highlightCurrentLine()
}
}
// highlight PC line
RVA PCAddr = Core()->getProgramCounterValue();
highlightSelection.cursor = cursor;
highlightSelection.cursor.movePosition(QTextCursor::Start);
if (PCAddr != RVA_INVALID) {
while (true) {
RVA lineOffset = readDisassemblyOffset(highlightSelection.cursor);
if (lineOffset == PCAddr) {
highlightSelection.format.setBackground(highlightPCColor);
highlightSelection.format.setProperty(QTextFormat::FullWidthSelection, true);
highlightSelection.cursor.clearSelection();
extraSelections.append(highlightSelection);
} else if (lineOffset != RVA_INVALID && lineOffset > PCAddr) {
break;
}
highlightSelection.cursor.movePosition(QTextCursor::EndOfLine);
if (highlightSelection.cursor.atEnd()) {
break;
}
highlightSelection.cursor.movePosition(QTextCursor::Down);
}
}
mDisasTextEdit->setExtraSelections(extraSelections);
}