1
0
Fork 0

GUI: fixed various bugs with QThread (should fix issue #312, couldn't reproduce it at least)

This commit is contained in:
Mr. eXoDia 2015-06-06 20:31:57 +02:00
parent c0c9e1acdf
commit 0c792c96eb
13 changed files with 151 additions and 126 deletions

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,8 @@
#include "MainWindowCloseThread.h"
#include "NewTypes.h"
void MainWindowCloseThread::run()
{
DbgExit();
emit canClose();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 += \