GUI: fixed various bugs with QThread (should fix issue #312, couldn't reproduce it at least)
This commit is contained in:
parent
c0c9e1acdf
commit
0c792c96eb
|
|
@ -14,7 +14,9 @@ CalculatorDialog::CalculatorDialog(QWidget* parent) : QDialog(parent), ui(new Ui
|
|||
ui->txtExpression->setText("0");
|
||||
ui->txtExpression->selectAll();
|
||||
ui->txtExpression->setFocus();
|
||||
mValidateThread = new CalculatorDialogValidateThread(this);
|
||||
mValidateThread = new ValidateExpressionThread();
|
||||
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, int_t)), this, SLOT(expressionChanged(bool, bool, int_t)));
|
||||
connect(ui->txtExpression, SIGNAL(textEdited(QString)), mValidateThread, SLOT(textChanged(QString)));
|
||||
}
|
||||
|
||||
CalculatorDialog::~CalculatorDialog()
|
||||
|
|
@ -40,13 +42,9 @@ void CalculatorDialog::setExpressionFocus()
|
|||
ui->txtExpression->setFocus();
|
||||
}
|
||||
|
||||
void CalculatorDialog::validateExpression()
|
||||
void CalculatorDialog::expressionChanged(bool validExpression, bool validPointer, int_t value)
|
||||
{
|
||||
QString expression = ui->txtExpression->text();
|
||||
if(expressionText == expression)
|
||||
return;
|
||||
expressionText = expression;
|
||||
if(!DbgIsValidExpression(expression.toUtf8().constData()))
|
||||
if(!validExpression)
|
||||
{
|
||||
ui->txtBin->setText("");
|
||||
ui->txtSignedDec->setText("");
|
||||
|
|
@ -61,17 +59,16 @@ void CalculatorDialog::validateExpression()
|
|||
else
|
||||
{
|
||||
ui->txtExpression->setStyleSheet("");
|
||||
uint_t ans = DbgValFromString(expression.toUtf8().constData());
|
||||
ui->txtHex->setText(inFormat(ans, N_HEX));
|
||||
ui->txtSignedDec->setText(inFormat(ans, N_SDEC));
|
||||
ui->txtUnsignedDec->setText(inFormat(ans, N_UDEC));
|
||||
ui->txtHex->setText(inFormat(value, N_HEX));
|
||||
ui->txtSignedDec->setText(inFormat(value, N_SDEC));
|
||||
ui->txtUnsignedDec->setText(inFormat(value, N_UDEC));
|
||||
int cursorpos = ui->txtBin->cursorPosition();
|
||||
ui->txtBin->setText(inFormat(ans, N_BIN));
|
||||
ui->txtBin->setText(inFormat(value, N_BIN));
|
||||
ui->txtBin->setCursorPosition(cursorpos);
|
||||
ui->txtOct->setText(inFormat(ans, N_OCT));
|
||||
if((ans == (ans & 0xFF)))
|
||||
ui->txtOct->setText(inFormat(value, N_OCT));
|
||||
if((value == (value & 0xFF)))
|
||||
{
|
||||
QChar c = QChar::fromLatin1((char)ans);
|
||||
QChar c = QChar::fromLatin1((char)value);
|
||||
if(c.isPrint())
|
||||
ui->txtAscii->setText("'" + QString(c) + "'");
|
||||
else
|
||||
|
|
@ -80,9 +77,9 @@ void CalculatorDialog::validateExpression()
|
|||
else
|
||||
ui->txtAscii->setText("???");
|
||||
ui->txtAscii->setCursorPosition(1);
|
||||
if((ans == (ans & 0xFFF))) //UNICODE?
|
||||
if((value == (value & 0xFFF))) //UNICODE?
|
||||
{
|
||||
QChar c = QChar::fromLatin1((wchar_t)ans);
|
||||
QChar c = QChar::fromLatin1((wchar_t)value);
|
||||
if(c.isPrint())
|
||||
ui->txtUnicode->setText("L'" + QString(c) + "'");
|
||||
else
|
||||
|
|
@ -93,7 +90,7 @@ void CalculatorDialog::validateExpression()
|
|||
ui->txtUnicode->setText("????");
|
||||
}
|
||||
ui->txtUnicode->setCursorPosition(2);
|
||||
emit validAddress(DbgMemIsValidReadPtr(ans));
|
||||
emit validAddress(validPointer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define CALCULATORDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QThread>
|
||||
#include "ValidateExpressionThread.h"
|
||||
#include "NewTypes.h"
|
||||
|
||||
namespace Ui
|
||||
|
|
@ -29,7 +29,6 @@ public:
|
|||
explicit CalculatorDialog(QWidget* parent = 0);
|
||||
~CalculatorDialog();
|
||||
void setExpressionFocus();
|
||||
void validateExpression();
|
||||
void showEvent(QShowEvent* event);
|
||||
void hideEvent(QHideEvent* event);
|
||||
|
||||
|
|
@ -38,6 +37,7 @@ signals:
|
|||
void showCpu();
|
||||
|
||||
private slots:
|
||||
void expressionChanged(bool validExpression, bool validPointer, int_t value);
|
||||
void on_btnGoto_clicked();
|
||||
void on_txtHex_textEdited(const QString & arg1);
|
||||
void on_txtSignedDec_textEdited(const QString & arg1);
|
||||
|
|
@ -49,32 +49,9 @@ private slots:
|
|||
void on_txtExpression_textChanged(const QString & arg1);
|
||||
|
||||
private:
|
||||
QString expressionText;
|
||||
QThread* mValidateThread;
|
||||
ValidateExpressionThread* mValidateThread;
|
||||
Ui::CalculatorDialog* ui;
|
||||
QString inFormat(const uint_t val, CalculatorDialog::NUMBERFORMAT NF) const;
|
||||
};
|
||||
|
||||
class CalculatorDialogValidateThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CalculatorDialogValidateThread(CalculatorDialog* calculatorDialog)
|
||||
{
|
||||
mCalculatorDialog = calculatorDialog;
|
||||
}
|
||||
|
||||
private:
|
||||
CalculatorDialog* mCalculatorDialog;
|
||||
|
||||
void run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
mCalculatorDialog->validateExpression();
|
||||
Sleep(50);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CALCULATORDIALOG_H
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ GotoDialog::GotoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::GotoDialog
|
|||
validRangeStart = 0;
|
||||
validRangeEnd = 0;
|
||||
fileOffset = false;
|
||||
mValidateThread = new GotoDialogValidateThread(this);
|
||||
mValidateThread = new ValidateExpressionThread();
|
||||
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, int_t)), this, SLOT(expressionChanged(bool, bool, int_t)));
|
||||
connect(ui->editExpression, SIGNAL(textEdited(QString)), mValidateThread, SLOT(textChanged(QString)));
|
||||
connect(this, SIGNAL(finished(int)), this, SLOT(finishedSlot(int)));
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +43,7 @@ void GotoDialog::hideEvent(QHideEvent* event)
|
|||
mValidateThread->terminate();
|
||||
}
|
||||
|
||||
void GotoDialog::validateExpression()
|
||||
void GotoDialog::expressionChanged(bool validExpression, bool validPointer, int_t value)
|
||||
{
|
||||
QString expression = ui->editExpression->text();
|
||||
if(expressionText == expression)
|
||||
|
|
@ -52,7 +54,7 @@ void GotoDialog::validateExpression()
|
|||
ui->buttonOk->setEnabled(false);
|
||||
expressionText.clear();
|
||||
}
|
||||
else if(!DbgIsValidExpression(expression.toUtf8().constData())) //invalid expression
|
||||
else if(!validExpression) //invalid expression
|
||||
{
|
||||
ui->labelError->setText("<font color='red'><b>Invalid expression...</b></font>");
|
||||
ui->buttonOk->setEnabled(false);
|
||||
|
|
@ -60,7 +62,7 @@ void GotoDialog::validateExpression()
|
|||
}
|
||||
else if(fileOffset)
|
||||
{
|
||||
uint_t offset = DbgValFromString(expression.toUtf8().constData());
|
||||
uint_t offset = value;
|
||||
uint_t va = DbgFunctions()->FileOffsetToVa(modName.toUtf8().constData(), offset);
|
||||
if(va)
|
||||
{
|
||||
|
|
@ -78,8 +80,8 @@ void GotoDialog::validateExpression()
|
|||
}
|
||||
else
|
||||
{
|
||||
uint_t addr = DbgValFromString(expression.toUtf8().constData());
|
||||
if(!DbgMemIsValidReadPtr(addr))
|
||||
uint_t addr = value;
|
||||
if(!validPointer)
|
||||
{
|
||||
ui->labelError->setText("<font color='red'><b>Invalid memory address...</b></font>");
|
||||
ui->buttonOk->setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define GOTODIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QThread>
|
||||
#include "ValidateExpressionThread.h"
|
||||
#include "NewTypes.h"
|
||||
|
||||
namespace Ui
|
||||
|
|
@ -24,39 +24,17 @@ public:
|
|||
QString modName;
|
||||
void showEvent(QShowEvent* event);
|
||||
void hideEvent(QHideEvent* event);
|
||||
void validateExpression();
|
||||
|
||||
private slots:
|
||||
void expressionChanged(bool validExpression, bool validPointer, int_t value);
|
||||
void on_editExpression_textChanged(const QString & arg1);
|
||||
void on_buttonOk_clicked();
|
||||
void finishedSlot(int result);
|
||||
|
||||
private:
|
||||
Ui::GotoDialog* ui;
|
||||
QThread* mValidateThread;
|
||||
ValidateExpressionThread* mValidateThread;
|
||||
bool IsValidMemoryRange(uint_t addr);
|
||||
};
|
||||
|
||||
class GotoDialogValidateThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GotoDialogValidateThread(GotoDialog* gotoDialog)
|
||||
{
|
||||
mGotoDialog = gotoDialog;
|
||||
}
|
||||
|
||||
private:
|
||||
GotoDialog* mGotoDialog;
|
||||
|
||||
void run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
mGotoDialog->validateExpression();
|
||||
Sleep(50);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GOTODIALOG_H
|
||||
|
|
|
|||
|
|
@ -230,35 +230,29 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||
|
||||
refreshShortcuts();
|
||||
|
||||
bClose = false;
|
||||
//setup close thread and dialog
|
||||
bCanClose = false;
|
||||
mCloseThread = new MainWindowCloseThread();
|
||||
connect(mCloseThread, SIGNAL(canClose()), this, SLOT(canClose()));
|
||||
mCloseDialog = new CloseDialog(this);
|
||||
|
||||
mCpuWidget->mDisas->setFocus();
|
||||
}
|
||||
|
||||
DWORD WINAPI MainWindow::closeThread(void* ptr)
|
||||
{
|
||||
DbgExit();
|
||||
MainWindow* mainWindow = (MainWindow*)ptr;
|
||||
mainWindow->bClose = true;
|
||||
mainWindow->close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
hide(); //hide main window
|
||||
mCloseDialog->show();
|
||||
mCloseDialog->setFocus();
|
||||
static bool bExecuteThread = true;
|
||||
static volatile bool bExecuteThread = true;
|
||||
if(bExecuteThread)
|
||||
{
|
||||
bExecuteThread = false;
|
||||
CloseSnowman(mSnowmanView);
|
||||
Sleep(100);
|
||||
bExecuteThread = false;
|
||||
CloseHandle(CreateThread(0, 0, closeThread, this, 0, 0));
|
||||
mCloseThread->start();
|
||||
}
|
||||
if(bClose)
|
||||
if(bCanClose)
|
||||
event->accept();
|
||||
else
|
||||
event->ignore();
|
||||
|
|
@ -1119,3 +1113,9 @@ void MainWindow::decompileAt(int_t start, int_t end)
|
|||
{
|
||||
DecompileAt(mSnowmanView, start, end);
|
||||
}
|
||||
|
||||
void MainWindow::canClose()
|
||||
{
|
||||
bCanClose = true;
|
||||
close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "UpdateChecker.h"
|
||||
#include "SourceViewerManager.h"
|
||||
#include "SnowmanView.h"
|
||||
#include "MainWindowCloseThread.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
|
@ -37,7 +38,6 @@ public:
|
|||
static DWORD WINAPI closeThread(void* ptr);
|
||||
void closeEvent(QCloseEvent* event);
|
||||
void setTab(QWidget* widget);
|
||||
bool bClose;
|
||||
|
||||
public slots:
|
||||
void executeCommand();
|
||||
|
|
@ -103,6 +103,7 @@ public slots:
|
|||
void detach();
|
||||
void changeCommandLine();
|
||||
void decompileAt(int_t start, int_t end);
|
||||
void canClose();
|
||||
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
|
|
@ -174,6 +175,9 @@ private:
|
|||
void initMenuApi();
|
||||
const MenuInfo* findMenu(int hMenu);
|
||||
|
||||
bool bCanClose;
|
||||
MainWindowCloseThread* mCloseThread;
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent* pEvent);
|
||||
void dropEvent(QDropEvent* pEvent);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ WordEditDialog::WordEditDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Wo
|
|||
#endif
|
||||
setModal(true);
|
||||
|
||||
mValidateThread = new WordEditDialogValidateThread(this);
|
||||
mValidateThread = new ValidateExpressionThread();
|
||||
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, int_t)), this, SLOT(expressionChanged(bool, bool, int_t)));
|
||||
connect(ui->expressionLineEdit, SIGNAL(textEdited(QString)), mValidateThread, SLOT(textChanged(QString)));
|
||||
mWord = 0;
|
||||
}
|
||||
|
||||
|
|
@ -45,13 +47,10 @@ uint_t WordEditDialog::getVal()
|
|||
return mWord;
|
||||
}
|
||||
|
||||
void WordEditDialog::validateExpression()
|
||||
void WordEditDialog::expressionChanged(bool validExpression, bool validPointer, int_t value)
|
||||
{
|
||||
QString expression = ui->expressionLineEdit->text();
|
||||
if(expressionText == expression)
|
||||
return;
|
||||
expressionText = expression;
|
||||
if(DbgIsValidExpression(expression.toUtf8().constData()))
|
||||
Q_UNUSED(validPointer);
|
||||
if(validExpression)
|
||||
{
|
||||
ui->expressionLineEdit->setStyleSheet("");
|
||||
ui->unsignedLineEdit->setStyleSheet("");
|
||||
|
|
@ -59,7 +58,7 @@ void WordEditDialog::validateExpression()
|
|||
ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
|
||||
//hex
|
||||
mWord = DbgValFromString(expression.toUtf8().constData());
|
||||
mWord = value;
|
||||
uint_t hexWord = 0;
|
||||
unsigned char* hex = (unsigned char*)&hexWord;
|
||||
unsigned char* word = (unsigned char*)&mWord;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
#define WORDEDITDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QThread>
|
||||
#include <QPushButton>
|
||||
#include "ValidateExpressionThread.h"
|
||||
#include "NewTypes.h"
|
||||
|
||||
namespace Ui
|
||||
|
|
@ -22,9 +22,9 @@ public:
|
|||
uint_t getVal();
|
||||
void showEvent(QShowEvent* event);
|
||||
void hideEvent(QHideEvent* event);
|
||||
void validateExpression();
|
||||
|
||||
private slots:
|
||||
void expressionChanged(bool validExpression, bool validPointer, int_t value);
|
||||
void on_expressionLineEdit_textChanged(const QString & arg1);
|
||||
void on_signedLineEdit_textEdited(const QString & arg1);
|
||||
void on_unsignedLineEdit_textEdited(const QString & arg1);
|
||||
|
|
@ -32,30 +32,7 @@ private slots:
|
|||
private:
|
||||
Ui::WordEditDialog* ui;
|
||||
uint_t mWord;
|
||||
QString expressionText;
|
||||
QThread* mValidateThread;
|
||||
};
|
||||
|
||||
class WordEditDialogValidateThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WordEditDialogValidateThread(WordEditDialog* wordEditDialog)
|
||||
{
|
||||
mWordEditDialog = wordEditDialog;
|
||||
}
|
||||
|
||||
private:
|
||||
WordEditDialog* mWordEditDialog;
|
||||
|
||||
void run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
mWordEditDialog->validateExpression();
|
||||
Sleep(50);
|
||||
}
|
||||
}
|
||||
ValidateExpressionThread* mValidateThread;
|
||||
};
|
||||
|
||||
#endif // WORDEDITDIALOG_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#include "MainWindowCloseThread.h"
|
||||
#include "NewTypes.h"
|
||||
|
||||
void MainWindowCloseThread::run()
|
||||
{
|
||||
DbgExit();
|
||||
emit canClose();
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef MAINWINDOWCLOSETHREAD_H
|
||||
#define MAINWINDOWCLOSETHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
class MainWindowCloseThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void canClose();
|
||||
|
||||
private:
|
||||
void run();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOWCLOSETHREAD_H
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#include "ValidateExpressionThread.h"
|
||||
|
||||
ValidateExpressionThread::ValidateExpressionThread()
|
||||
{
|
||||
mExpressionChanged = false;
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::textChanged(QString text)
|
||||
{
|
||||
mExpressionMutex.lock();
|
||||
if(mExpressionText != text)
|
||||
mExpressionChanged = true;
|
||||
mExpressionText = text;
|
||||
mExpressionMutex.unlock();
|
||||
}
|
||||
|
||||
void ValidateExpressionThread::run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
mExpressionMutex.lock();
|
||||
QString expression = mExpressionText;
|
||||
bool changed = mExpressionChanged;
|
||||
mExpressionChanged = false;
|
||||
mExpressionMutex.unlock();
|
||||
if(changed)
|
||||
{
|
||||
duint value;
|
||||
bool validExpression = DbgFunctions()->ValFromString(expression.toUtf8().constData(), &value);
|
||||
bool validPointer = validExpression && DbgMemIsValidReadPtr(value);
|
||||
emit expressionChanged(validExpression, validPointer, value);
|
||||
}
|
||||
Sleep(50);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef VALIDATEEXPRESSIONTHREAD_H
|
||||
#define VALIDATEEXPRESSIONTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include "NewTypes.h"
|
||||
|
||||
class ValidateExpressionThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ValidateExpressionThread();
|
||||
|
||||
signals:
|
||||
void expressionChanged(bool validExpression, bool validPointer, int_t value);
|
||||
|
||||
public slots:
|
||||
void textChanged(QString text);
|
||||
|
||||
private:
|
||||
QMutex mExpressionMutex;
|
||||
QString mExpressionText;
|
||||
bool mExpressionChanged;
|
||||
|
||||
void run();
|
||||
};
|
||||
|
||||
#endif // VALIDATEEXPRESSIONTHREAD_H
|
||||
|
|
@ -90,7 +90,9 @@ SOURCES += \
|
|||
Src/Gui/YaraRuleSelectionDialog.cpp \
|
||||
Src/Gui/DataCopyDialog.cpp \
|
||||
Src/Gui/SourceViewerManager.cpp \
|
||||
Src/Gui/SourceView.cpp
|
||||
Src/Gui/SourceView.cpp \
|
||||
Src/Utils/ValidateExpressionThread.cpp \
|
||||
Src/Utils/MainWindowCloseThread.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
|
|
@ -160,7 +162,9 @@ HEADERS += \
|
|||
Src/Gui/DataCopyDialog.h \
|
||||
Src/Gui/SourceViewerManager.h \
|
||||
Src/Gui/SourceView.h \
|
||||
Src/Utils/StringUtil.h
|
||||
Src/Utils/StringUtil.h \
|
||||
Src/Utils/ValidateExpressionThread.h \
|
||||
Src/Utils/MainWindowCloseThread.h
|
||||
|
||||
|
||||
INCLUDEPATH += \
|
||||
|
|
|
|||
Loading…
Reference in New Issue