Display jumping fix useless decompilation (#2351)

* save scroll position and reset to that if the newly decompiled function is the same as the previous one

* instructionChanged signal replaced completely by breakpointsChanged in toggle/add breakpoint functions.

* removed addbreakpoint(QString) and toggleBreakpoint(QString)
This commit is contained in:
NIRMAL MANOJ C 2020-08-02 15:21:56 +05:30
parent 37fc01478f
commit b42a19e995
7 changed files with 55 additions and 37 deletions

View File

@ -2068,23 +2068,7 @@ void CutterCore::setDebugPlugin(QString plugin)
void CutterCore::toggleBreakpoint(RVA addr)
{
cmdRaw(QString("dbs %1").arg(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
}
void CutterCore::toggleBreakpoint(QString addr)
{
cmdRaw("dbs " + addr);
emit instructionChanged(addr.toULongLong());
emit breakpointsChanged();
}
void CutterCore::addBreakpoint(QString addr)
{
cmdRaw("db " + addr);
emit instructionChanged(addr.toULongLong());
emit breakpointsChanged();
emit breakpointsChanged(addr);
}
void CutterCore::addBreakpoint(const BreakpointDescription &config)
@ -2138,8 +2122,7 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config)
if (!config.command.isEmpty()) {
updateOwnedCharPtr(breakpoint->data, config.command);
}
emit instructionChanged(breakpoint->addr);
emit breakpointsChanged();
emit breakpointsChanged(breakpoint->addr);
}
void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config)
@ -2157,8 +2140,7 @@ void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config
void CutterCore::delBreakpoint(RVA addr)
{
cmdRaw("db- " + RAddressString(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}
void CutterCore::delAllBreakpoints()
@ -2170,15 +2152,13 @@ void CutterCore::delAllBreakpoints()
void CutterCore::enableBreakpoint(RVA addr)
{
cmdRaw("dbe " + RAddressString(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}
void CutterCore::disableBreakpoint(RVA addr)
{
cmdRaw("dbd " + RAddressString(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}
void CutterCore::setBreakpointTrace(int index, bool enabled)

View File

@ -391,11 +391,9 @@ public:
void stepOverDebug();
void stepOutDebug();
void addBreakpoint(QString addr);
void addBreakpoint(const BreakpointDescription &config);
void updateBreakpoint(int index, const BreakpointDescription &config);
void toggleBreakpoint(RVA addr);
void toggleBreakpoint(QString addr);
void delBreakpoint(RVA addr);
void delAllBreakpoints();
void enableBreakpoint(RVA addr);
@ -643,7 +641,7 @@ signals:
void commentsChanged();
void registersChanged();
void instructionChanged(RVA offset);
void breakpointsChanged();
void breakpointsChanged(RVA offset);
void refreshCodeViews();
void stackChanged();
/**

View File

@ -15,11 +15,18 @@
#include <QClipboard>
#include <QObject>
#include <QTextBlockUserData>
#include <QScrollBar>
#include <QAbstractSlider>
DecompilerWidget::DecompilerWidget(MainWindow *main) :
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
mCtxMenu(new DecompilerContextMenu(this, main)),
ui(new Ui::DecompilerWidget),
decompilerWasBusy(false),
scrollerHorizontal(0),
scrollerVertical(0),
previousFunctionAddr(RVA_INVALID),
decompiledFunctionAddr(RVA_INVALID),
code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")),
&r_annotated_code_free)
{
@ -38,9 +45,6 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC);
connect(mCtxMenu, &DecompilerContextMenu::copy, this, &DecompilerWidget::copy);
decompiledFunctionAddr = RVA_INVALID;
decompilerWasBusy = false;
connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
doRefresh();
});
@ -88,7 +92,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
connect(ui->textEdit, &QWidget::customContextMenuRequested,
this, &DecompilerWidget::showDisasContextMenu);
connect(Core(), &CutterCore::breakpointsChanged, this, &DecompilerWidget::setInfoForBreakpoints);
connect(Core(), &CutterCore::breakpointsChanged, this, &DecompilerWidget::updateBreakpoints);
addActions(mCtxMenu->actions());
ui->progressLabel->setVisible(false);
@ -182,6 +186,19 @@ static size_t positionForOffset(RAnnotatedCode &codeDecompiled, ut64 offset)
return closestPos;
}
void DecompilerWidget::updateBreakpoints()
{
setInfoForBreakpoints();
QTextCursor cursor = ui->textEdit->textCursor();
cursor.select(QTextCursor::Document);
cursor.setCharFormat(QTextCharFormat());
cursor.setBlockFormat(QTextBlockFormat());
ui->textEdit->setExtraSelections({});
highlightPC();
highlightBreakpoints();
updateSelection();
}
void DecompilerWidget::setInfoForBreakpoints()
{
if (mCtxMenu->getIsTogglingBreakpoints())
@ -250,6 +267,7 @@ void DecompilerWidget::doRefresh(RVA addr)
// Clear all selections since we just refreshed
ui->textEdit->setExtraSelections({});
previousFunctionAddr = decompiledFunctionAddr;
decompiledFunctionAddr = Core()->getFunctionStart(addr);
dec->decompileAt(addr);
if (dec->isRunning()) {
@ -280,6 +298,13 @@ QTextCursor DecompilerWidget::getCursorForAddress(RVA addr)
void DecompilerWidget::decompilationFinished(RAnnotatedCode *codeDecompiled)
{
bool isDisplayReset = false;
if (previousFunctionAddr == decompiledFunctionAddr) {
scrollerHorizontal = ui->textEdit->horizontalScrollBar()->sliderPosition();
scrollerVertical = ui->textEdit->verticalScrollBar()->sliderPosition();
isDisplayReset = true;
}
ui->progressLabel->setVisible(false);
ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled);
updateRefreshButton();
@ -303,6 +328,11 @@ void DecompilerWidget::decompilationFinished(RAnnotatedCode *codeDecompiled)
decompilerWasBusy = false;
doAutoRefresh();
}
if (isDisplayReset) {
ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollerHorizontal);
ui->textEdit->verticalScrollBar()->setSliderPosition(scrollerVertical);
}
}
void DecompilerWidget::setAnnotationsAtCursor(size_t pos)

View File

@ -56,6 +56,9 @@ private:
*/
bool decompilerWasBusy;
int scrollerHorizontal;
int scrollerVertical;
RVA previousFunctionAddr;
RVA decompiledFunctionAddr;
std::unique_ptr<RAnnotatedCode, void (*)(RAnnotatedCode *)> code;
bool seekFromCursor = false;
@ -113,6 +116,7 @@ private:
*/
void gatherBreakpointInfo(RAnnotatedCode &codeDecompiled, size_t startPos, size_t endPos);
void updateBreakpoints();
void setInfoForBreakpoints();
void setAnnotationsAtCursor(size_t pos);

View File

@ -47,6 +47,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(instructionChanged(RVA)), this, SLOT(refreshView()));
connect(Core(), &CutterCore::breakpointsChanged, this, &DisassemblerGraphView::refreshView);
connect(Core(), SIGNAL(functionsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshView()));

View File

@ -151,11 +151,8 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main)
connect(Core(), &CutterCore::functionRenamed, this, [this]() {refreshDisasm();});
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshDisasm()));
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshDisasm()));
connect(Core(), &CutterCore::instructionChanged, this, [this](RVA offset) {
if (offset >= topOffset && offset <= bottomOffset) {
refreshDisasm();
}
});
connect(Core(), &CutterCore::instructionChanged, this, &DisassemblyWidget::refreshIfInRange);
connect(Core(), &CutterCore::breakpointsChanged, this, &DisassemblyWidget::refreshIfInRange);
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshDisasm()));
connect(Config(), &Configuration::fontsUpdated, this, &DisassemblyWidget::fontsUpdatedSlot);
@ -249,6 +246,13 @@ QList<DisassemblyLine> DisassemblyWidget::getLines()
return lines;
}
void DisassemblyWidget::refreshIfInRange(RVA offset)
{
if (offset >= topOffset && offset <= bottomOffset) {
refreshDisasm();
}
}
void DisassemblyWidget::refreshDisasm(RVA offset)
{
if(!disasmRefresh->attemptRefresh(offset == RVA_INVALID ? nullptr : new RVA(offset))) {

View File

@ -40,6 +40,7 @@ public slots:
protected slots:
void on_seekChanged(RVA offset);
void refreshIfInRange(RVA offset);
void refreshDisasm(RVA offset = RVA_INVALID);
bool updateMaxLines();