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(); 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) void CutterCore::setRegister(QString regName, QString regValue)
{ {
cmd("dr " + regName + "=" + regValue); cmd("dr " + regName + "=" + regValue);
@ -774,10 +786,12 @@ void CutterCore::stopDebug()
{ {
// @TODO should first obtain correct signal to send. // @TODO should first obtain correct signal to send.
// Also, we do a ds since otherwise the process does not die. // Also, we do a ds since otherwise the process does not die.
if (currentlyDebugging) {
cmd("dk 9; ds; e cfg.debug = false; oo"); cmd("dk 9; ds; e cfg.debug = false; oo");
seek(offsetPriorDebugging); seek(offsetPriorDebugging);
emit changeDefinedView(); emit changeDefinedView();
currentlyDebugging = false; currentlyDebugging = false;
}
} }
void CutterCore::continueDebug() void CutterCore::continueDebug()
@ -795,7 +809,7 @@ void CutterCore::continueUntilDebug(QString offset)
void CutterCore::continueUntilCall() void CutterCore::continueUntilCall()
{ {
cmd("dcc"); cmd("dcc");
QString programCounterValue = cmd("dr?`drn pc`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seek(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
@ -803,7 +817,7 @@ void CutterCore::continueUntilCall()
void CutterCore::continueUntilSyscall() void CutterCore::continueUntilSyscall()
{ {
cmd("dcs"); cmd("dcs");
QString programCounterValue = cmd("dr?`drn pc`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seek(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
@ -811,7 +825,7 @@ void CutterCore::continueUntilSyscall()
void CutterCore::stepDebug() void CutterCore::stepDebug()
{ {
cmd("ds"); cmd("ds");
QString programCounterValue = cmd("dr?`drn pc`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seek(programCounterValue);
emit registersChanged(); emit registersChanged();
} }
@ -819,7 +833,7 @@ void CutterCore::stepDebug()
void CutterCore::stepOverDebug() void CutterCore::stepOverDebug()
{ {
cmd("dso"); cmd("dso");
QString programCounterValue = cmd("dr?`drn pc`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seek(programCounterValue);
emit registersChanged(); emit registersChanged();
} }

View File

@ -475,6 +475,7 @@ public:
QJsonDocument getRegistersInfo(); QJsonDocument getRegistersInfo();
QJsonDocument getRegisterValues(); QJsonDocument getRegisterValues();
QString getRegisterName(QString registerRole); QString getRegisterName(QString registerRole);
RVA getProgramCounterValue();
void setRegister(QString regName, QString regValue); void setRegister(QString regName, QString regValue);
QJsonDocument getStack(int size = 0x40); QJsonDocument getStack(int size = 0x40);
QJsonDocument getBacktrace(); QJsonDocument getBacktrace();
@ -494,6 +495,7 @@ public:
QString getActiveDebugPlugin(); QString getActiveDebugPlugin();
QStringList getDebugPlugins(); QStringList getDebugPlugins();
void setDebugPlugin(QString plugin); void setDebugPlugin(QString plugin);
bool currentlyDebugging = false;
RVA getOffsetJump(RVA addr); RVA getOffsetJump(RVA addr);
QString getDecompiledCode(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!"), tr("Do you really want to exit?\nSave your project before closing!"),
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)); (QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
if (ret == QMessageBox::Save) { if (ret == QMessageBox::Save) {
if (saveProject(true)) { if (saveProject(true) && !Core()->currentlyDebugging) {
saveSettings(); saveSettings();
} }
QMainWindow::closeEvent(event); QMainWindow::closeEvent(event);
} else if (ret == QMessageBox::Discard) { } else if (ret == QMessageBox::Discard) {
if (!Core()->currentlyDebugging) {
saveSettings(); saveSettings();
}
QMainWindow::closeEvent(event); QMainWindow::closeEvent(event);
} else { } else {
event->ignore(); event->ignore();

View File

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

View File

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

View File

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

View File

@ -310,6 +310,7 @@ void DisassemblyWidget::highlightCurrentLine()
QList<QTextEdit::ExtraSelection> extraSelections; QList<QTextEdit::ExtraSelection> extraSelections;
QColor highlightColor = ConfigColor("highlight"); QColor highlightColor = ConfigColor("highlight");
QColor highlightPCColor = ConfigColor("highlightPC");
QColor highlightWordColor = ConfigColor("highlightWord"); QColor highlightWordColor = ConfigColor("highlightWord");
highlightWordColor.setAlpha(128); highlightWordColor.setAlpha(128);
QColor highlightWordCurrentLineColor = ConfigColor("gui.background"); 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); mDisasTextEdit->setExtraSelections(extraSelections);
} }