1
0
Fork 0

Revert "Added ability to roughly measure UI latency; code to try and maintain that latency at <50ms" (#859)

This commit is contained in:
Duncan Ogilvie 2016-07-17 14:42:23 +02:00 committed by GitHub
parent 85e147a6ab
commit 8c1981361a
28 changed files with 88 additions and 377 deletions

View File

@ -1,7 +1,6 @@
#include "_global.h"
GUIGUIINIT _gui_guiinit;
GUIMESSAGELATENCY _gui_messagelatency;
GUISENDMESSAGE _gui_sendmessage;
GUISENDMESSAGEASYNC _gui_sendmessageasync;

View File

@ -6,13 +6,11 @@
//GUI typedefs
typedef int (*GUIGUIINIT)(int, char**);
typedef uint32(*GUIMESSAGELATENCY)();
typedef void* (*GUISENDMESSAGE)(GUIMSG type, void* param1, void* param2);
typedef void (*GUISENDMESSAGEASYNC)(GUIMSG type, void* param1, void* param2);
//GUI functions
extern GUIGUIINIT _gui_guiinit;
extern GUIMESSAGELATENCY _gui_messagelatency;
extern GUISENDMESSAGE _gui_sendmessage;
extern GUISENDMESSAGEASYNC _gui_sendmessageasync;

View File

@ -64,7 +64,6 @@ BRIDGE_IMPEXP const wchar_t* BridgeInit()
//GUI Load
LOADLIBRARY(gui_lib);
LOADEXPORT(_gui_guiinit);
LOADEXPORT(_gui_messagelatency);
LOADEXPORT(_gui_sendmessage);
//DBG Load
@ -996,13 +995,6 @@ BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state)
_gui_sendmessage(GUI_SET_DEBUG_STATE, (void*)state, 0);
}
BRIDGE_IMPEXP DWORD GuiGetLatency()
{
return _gui_messagelatency();
}
BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg)
{
_gui_sendmessage(GUI_ADD_MSG_TO_LOG, (void*)msg, 0);

View File

@ -25,12 +25,6 @@ typedef unsigned long duint;
typedef signed long dsint;
#endif //_WIN64
typedef int int32;
typedef unsigned int uint32;
typedef long long int64;
typedef unsigned long long uint64;
#include "bridgegraph.h"
#ifndef BRIDGE_IMPEXP
@ -985,7 +979,6 @@ typedef struct
//GUI functions
//code page is utf8
BRIDGE_IMPEXP DWORD GuiGetLatency();
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip);
BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state);
BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg);

View File

@ -140,7 +140,7 @@ typedef TRACERECORDTYPE(*GETTRACERECORDTYPE)(duint pageAddress);
typedef bool(*ENUMHANDLES)(ListOf(HANDLEINFO) handles);
typedef bool(*GETHANDLENAME)(duint handle, char* name, size_t nameSize, char* typeName, size_t typeNameSize);
typedef bool(*ENUMTCPCONNECTIONS)(ListOf(TCPCONNECTIONINFO) connections);
typedef uint64(*GETDBGEVENTS)();
typedef duint(*GETDBGEVENTS)();
typedef int(*MODGETPARTY)(duint base);
typedef void(*MODSETPARTY)(duint base, int party);
typedef bool(*WATCHISWATCHDOGTRIGGERED)(unsigned int id);

View File

@ -230,7 +230,6 @@ bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition)
return false;
strcpy_s(bpInfo->breakCondition, Condition);
DebugUpdateBreakpointsViewAsync();
return true;
}
@ -246,7 +245,6 @@ bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log)
return false;
strcpy_s(bpInfo->logText, Log);
DebugUpdateBreakpointsViewAsync();
return true;
}
@ -292,7 +290,6 @@ bool BpSetCommandCondition(duint Address, BP_TYPE Type, const char* Condition)
return false;
strcpy_s(bpInfo->commandCondition, Condition);
DebugUpdateBreakpointsViewAsync();
return true;
}
@ -308,8 +305,6 @@ bool BpSetFastResume(duint Address, BP_TYPE Type, bool fastResume)
return false;
bpInfo->fastResume = fastResume;
DebugUpdateBreakpointsViewAsync();
return true;
}

View File

@ -84,7 +84,7 @@ HANDLE hProcessToken;
bool bUndecorateSymbolNames = true;
bool bEnableSourceDebugging = true;
bool bTraceRecordEnabledDuringTrace = true;
uint64 DbgEvents = 0;
duint DbgEvents = 0;
static duint dbgcleartracecondition()
{
@ -280,9 +280,9 @@ bool dbgcmddel(const char* name)
return true;
}
uint64 dbggetdbgevents()
duint dbggetdbgevents()
{
return InterlockedCompareExchange64((int64*)&DbgEvents, -1, -1);
return InterlockedExchange(&DbgEvents, 0);
}
static DWORD WINAPI updateCallStackThread(duint ptr)
@ -356,56 +356,23 @@ void DebugUpdateGui(duint disasm_addr, bool stack)
GuiFocusView(GUI_DISASSEMBLY);
}
void DebugUpdateGuiSetState(duint disasm_addr, bool stack, DBGSTATE state = paused, bool setDebugState = true)
void DebugUpdateGuiSetState(duint disasm_addr, bool stack, DBGSTATE state = paused)
{
if(setDebugState)
GuiSetDebugState(state);
if(disasm_addr != 0)
DebugUpdateGui(disasm_addr, stack);
GuiSetDebugState(state);
DebugUpdateGui(disasm_addr, stack);
}
typedef TaskThread_<decltype(&DebugUpdateGuiSetState), duint, bool, DBGSTATE, bool> UpdateGuiSetStateTaskBase;
struct UpdateGuiSetStateTask : public UpdateGuiSetStateTaskBase
{
UpdateGuiSetStateTask(UpdateGuiSetStateTaskBase::Fn_t f) : UpdateGuiSetStateTaskBase(f) {}
virtual UpdateGuiSetStateTaskBase::Args_t CompressArguments(duint && addr, bool && stack, DBGSTATE && state, bool && updateDebugState) override
{
// Addr and stack args are not simply set; if addr is 0 it doesn't change the current addr and we
// stack is sticky until its reset after running.
return std::make_tuple(
addr != 0 ? addr : std::get<0>(args),
stack || std::get<1>(args),
updateDebugState ? state : std::get<2>(args),
updateDebugState || std::get<3>(args));
}
virtual void ResetArgs() override
{
// Necessary or addr and stack would always be non-zero, and always would run
args = std::make_tuple(0, false, paused, false);
}
};
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state, bool updateDebugState)
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state)
{
//correctly orders the GuiSetDebugState DebugUpdateGui to prevent drawing inconsistencies
static UpdateGuiSetStateTask DebugUpdateGuiSetStateTask(&DebugUpdateGuiSetState);
DebugUpdateGuiSetStateTask.WakeUp(disasm_addr, stack, state, updateDebugState);
static TaskThread_<decltype(&DebugUpdateGuiSetState), duint, bool, DBGSTATE> DebugUpdateGuiSetStateTask(&DebugUpdateGuiSetState);
DebugUpdateGuiSetStateTask.WakeUp(disasm_addr, stack, state);
}
void DebugUpdateGuiAsync(duint disasm_addr, bool stack)
{
DebugUpdateGuiSetStateAsync(disasm_addr, stack, paused, false);
}
void GuiSetDebugStateAsync(DBGSTATE state)
{
DebugUpdateGuiSetStateAsync(0, false, state);
}
void DebugUpdateBreakpointsViewAsync()
{
static TaskThread_<decltype(&GuiUpdateBreakpointsView)> BreakpointsUpdateGuiTask(&GuiUpdateBreakpointsView);
BreakpointsUpdateGuiTask.WakeUp();
static TaskThread_<decltype(&DebugUpdateGui), duint, bool> DebugUpdateGuiTask(&DebugUpdateGui);
DebugUpdateGuiTask.WakeUp(disasm_addr, stack);
}
void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump)
@ -545,6 +512,12 @@ static bool getConditionValue(const char* expression)
return true;
}
void GuiSetDebugStateAsync(DBGSTATE state)
{
static TaskThread_<decltype(&GuiSetDebugState), DBGSTATE> GuiSetDebugStateTask(&GuiSetDebugState);
GuiSetDebugStateTask.WakeUp(state);
}
void cbPauseBreakpoint()
{
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
@ -1668,7 +1641,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
static void cbDebugEvent(DEBUG_EVENT* DebugEvent)
{
InterlockedIncrement64((int64_t*)&DbgEvents);
InterlockedIncrement(&DbgEvents);
PLUG_CB_DEBUGEVENT debugEventInfo;
debugEventInfo.DebugEvent = DebugEvent;
plugincbcall(CB_DEBUGEVENT, &debugEventInfo);

View File

@ -69,8 +69,7 @@ bool dbgisdll();
void dbgsetattachevent(HANDLE handle);
void DebugUpdateGui(duint disasm_addr, bool stack);
void DebugUpdateGuiAsync(duint disasm_addr, bool stack);
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state = paused, bool updateDebugState = true);
void DebugUpdateBreakpointsViewAsync();
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state = paused);
void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump = false);
void GuiSetDebugStateAsync(DBGSTATE state);
void dbgsetskipexceptions(bool skip);
@ -88,7 +87,7 @@ bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error);
bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error);
void dbgstartscriptthread(CBPLUGINSCRIPT cbScript);
duint dbggetdebuggedbase();
uint64 dbggetdbgevents();
duint dbggetdbgevents();
bool dbgsettracecondition(String expression, duint maxCount);
bool dbgtraceactive();

View File

@ -31,8 +31,6 @@ protected:
// Reset called after we latch in a value
virtual void ResetArgs() { }
public:
typedef F Fn_t;
typedef std::tuple<Args...> Args_t;
void WakeUp(Args...);
TaskThread_(F, size_t minSleepTimeMs = TASK_THREAD_DEFAULT_SLEEP_TIME);
~TaskThread_();
@ -130,11 +128,7 @@ template <typename F, typename... Args> void TaskThread_<F, Args...>::Loop()
if(active)
{
apply_from_tuple(fn, argLatch);
do
{
std::this_thread::sleep_for(std::chrono::milliseconds(minSleepTimeMs));
}
while(GuiGetLatency() > 100);
std::this_thread::sleep_for(std::chrono::milliseconds(minSleepTimeMs));
execs++;
}
}

View File

@ -221,6 +221,7 @@ HANDLE ThreadGetHandle(DWORD ThreadId)
if(threadList.find(ThreadId) != threadList.end())
return threadList[ThreadId].Handle;
ASSERT_ALWAYS("Trying to get handle of a thread that doesn't exist!");
return nullptr;
}

View File

@ -952,10 +952,10 @@ int AbstractTableView::getLineToPrintcount()
*
* @param[in] width Width of the column in pixel
* @param[in] isClickable Boolean that tells whether the header is clickable or not
* @param[in] sortFn The sort function to use for this column. Defaults to case insensitve text search
*
* @return Nothing.
*/
void AbstractTableView::addColumnAt(int width, const QString & title, bool isClickable, SortBy::t sortFn)
void AbstractTableView::addColumnAt(int width, const QString & title, bool isClickable)
{
HeaderButton_t wHeaderButton;
Column_t wColumn;
@ -969,7 +969,6 @@ void AbstractTableView::addColumnAt(int width, const QString & title, bool isCli
wColumn.width = width;
wColumn.hidden = false;
wColumn.title = title;
wColumn.sortFunction = sortFn;
wCurrentCount = mColumnList.length();
mColumnList.append(wColumn);
mColumnOrder.append(wCurrentCount);
@ -1007,12 +1006,12 @@ QString AbstractTableView::getColTitle(int index)
/************************************************************************************
Getter & Setter
************************************************************************************/
dsint AbstractTableView::getRowCount() const
dsint AbstractTableView::getRowCount()
{
return mRowCount;
}
int AbstractTableView::getColumnCount() const
int AbstractTableView::getColumnCount()
{
return mColumnList.size();
}
@ -1043,12 +1042,7 @@ bool AbstractTableView::getColumnHidden(int col)
else
return true;
}
AbstractTableView::SortBy::t AbstractTableView::getColumnSortBy(int col) const
{
if(col < getColumnCount() && col >= 0)
return mColumnList[col].sortFunction;
return SortBy::AsText;
}
void AbstractTableView::setColumnHidden(int col, bool hidden)
{
if(col < getColumnCount() && col >= 0)
@ -1172,6 +1166,7 @@ void AbstractTableView::updateViewport()
this->viewport()->update();
}
/**
* @brief This method is called when data have to be reloaded (e.g. When table offset changes).
*
@ -1183,18 +1178,3 @@ void AbstractTableView::prepareData()
dsint wRemainingRowsCount = getRowCount() - mTableOffset;
mNbrOfLineToPrint = (dsint)wRemainingRowsCount > (dsint)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount;
}
bool AbstractTableView::SortBy::AsText(const QString & a, const QString & b)
{
return QString::compare(a, b, Qt::CaseInsensitive) < 0;
}
bool AbstractTableView::SortBy::AsInt(const QString & a, const QString & b)
{
return a.toLongLong() < b.toLongLong();
}
bool AbstractTableView::SortBy::AsHex(const QString & a, const QString & b)
{
return a.toLongLong(0, 16) < b.toLongLong(0, 16);
}

View File

@ -86,24 +86,16 @@ public:
int getViewableRowsCount();
virtual int getLineToPrintcount();
struct SortBy
{
typedef std::function<bool(const QString &, const QString &)> t;
static bool AsText(const QString & a, const QString & b);
static bool AsInt(const QString & a, const QString & b);
static bool AsHex(const QString & a, const QString & b);
};
// New Columns/New Size
virtual void addColumnAt(int width, const QString & title, bool isClickable, SortBy::t sortFn = SortBy::AsText);
virtual void addColumnAt(int width, const QString & title, bool isClickable);
virtual void setRowCount(dsint count);
virtual void deleteAllColumns();
void setColTitle(int index, const QString & title);
QString getColTitle(int index);
// Getter & Setter
dsint getRowCount() const;
int getColumnCount() const;
dsint getRowCount();
int getColumnCount();
int getRowHeight();
int getColumnWidth(int index);
void setColumnWidth(int index, int width);
@ -116,7 +108,6 @@ public:
int getCharWidth();
bool getColumnHidden(int col);
void setColumnHidden(int col, bool hidden);
SortBy::t getColumnSortBy(int idx) const;
// UI customization
void loadColumnFromConfig(const QString & viewName);
@ -176,7 +167,6 @@ private:
bool hidden;
HeaderButton_t header;
QString title;
SortBy::t sortFunction;
} Column_t;
typedef struct _Header_t

View File

@ -771,23 +771,18 @@ void Disassembly::keyPressEvent(QKeyEvent* event)
if(event->modifiers() & Qt::ShiftModifier) //SHIFT pressed
expand = true;
dsint initialStart = getSelectionStart();
if(key == Qt::Key_Up)
selectPrevious(expand);
else
selectNext(expand);
bool expandedUp = initialStart != getSelectionStart();
dsint modifiedSelection = expandedUp ? getSelectionStart() : getSelectionEnd();
if(modifiedSelection < botRVA)
if(getSelectionStart() < botRVA)
{
setTableOffset(modifiedSelection);
setTableOffset(getSelectionStart());
}
else if(modifiedSelection >= topRVA)
else if(getSelectionEnd() >= topRVA)
{
setTableOffset(getInstructionRVA(modifiedSelection, -getNbrOfLineToPrint() + 2));
setTableOffset(getInstructionRVA(getSelectionEnd(), -getNbrOfLineToPrint() + 2));
}
updateViewport();

View File

@ -1,43 +1,17 @@
#include "HistoryLineEdit.h"
#include "Bridge.h"
HistoryLineEdit::HistoryLineEdit(QWidget* parent) : QLineEdit(parent)
{
mCmdHistory.clear();
mCmdIndex = -1;
bSixPressed = false;
}
void HistoryLineEdit::loadSettings(QString sectionPrefix)
{
char buffer[MAX_SETTING_SIZE];
for(int i = 1; BridgeSettingGet(sectionPrefix.toUtf8().constData(),
QString("Line%1").arg(i).toUtf8().constData(),
buffer) && buffer[0] && i < mCmdHistoryMaxSize; i++)
{
QString entry = QString::fromUtf8(buffer);
mCmdHistory.append(entry);
}
}
void HistoryLineEdit::saveSettings(QString sectionPrefix)
{
int i = 1;
for(i = 1; i <= mCmdHistory.size(); i++)
{
BridgeSettingSet(sectionPrefix.toUtf8().constData(),
QString("Line%1").arg(i).toUtf8().constData(),
mCmdHistory.at(i - 1).toUtf8().constData());
}
// Sentinel in case we saved less than is in the store currently
BridgeSettingSet(sectionPrefix.toUtf8().constData(),
QString("Line%1").arg(i).toUtf8().constData(),
"");
}
void HistoryLineEdit::addLineToHistory(QString parLine)
{
mCmdHistory.prepend(parLine);
if(mCmdHistory.size() > mCmdHistoryMaxSize)
if(mCmdHistory.size() > 32)
mCmdHistory.removeLast();
mCmdIndex = -1;

View File

@ -12,13 +12,11 @@ public:
void keyPressEvent(QKeyEvent* event);
void addLineToHistory(QString parLine);
void setFocus();
void loadSettings(QString sectionPrefix);
void saveSettings(QString sectionPrefix);
signals:
void keyPressed(int parKey);
private:
int mCmdHistoryMaxSize = 1000;
QList<QString> mCmdHistory;
int mCmdIndex;
bool bSixPressed;

View File

@ -172,13 +172,11 @@ void StdTable::expandSelectionUpTo(int to)
{
mSelection.fromIndex = to;
mSelection.toIndex = mSelection.firstSelectedIndex;
emit selectionChangedSignal(to);
}
else if(to > mSelection.firstSelectedIndex)
{
mSelection.fromIndex = mSelection.firstSelectedIndex;
mSelection.toIndex = to;
emit selectionChangedSignal(to);
}
else if(to == mSelection.firstSelectedIndex)
{
@ -199,17 +197,6 @@ int StdTable::getInitialSelection()
return mSelection.firstSelectedIndex;
}
QList<int> StdTable::getSelection()
{
QList<int> selection;
selection.reserve(mSelection.toIndex - mSelection.fromIndex);
for(int i = mSelection.fromIndex; i <= mSelection.toIndex; i++)
{
selection.append(i);
}
return selection;
}
void StdTable::selectNext()
{
int wNext = getInitialSelection() + 1;
@ -245,9 +232,9 @@ bool StdTable::isSelected(int base, int offset)
/************************************************************************************
Data Management
************************************************************************************/
void StdTable::addColumnAt(int width, QString title, bool isClickable, QString copyTitle, SortBy::t sortFn)
void StdTable::addColumnAt(int width, QString title, bool isClickable, QString copyTitle)
{
AbstractTableView::addColumnAt(width, title, isClickable, sortFn);
AbstractTableView::addColumnAt(width, title, isClickable);
//append empty column to list of rows
for(int i = 0; i < mData.size(); i++)
@ -487,6 +474,6 @@ void StdTable::headerButtonPressedSlot(int col)
void StdTable::reloadData()
{
if(mSort.first != -1) //re-sort if the user wants to sort
qSort(mData.begin(), mData.end(), ColumnCompare(mSort.first, mSort.second, getColumnSortBy(mSort.first)));
qSort(mData.begin(), mData.end(), ColumnCompare(mSort.first, mSort.second));
AbstractTableView::reloadData();
}

View File

@ -24,13 +24,12 @@ public:
void expandSelectionUpTo(int to);
void setSingleSelection(int index);
int getInitialSelection();
QList<int> getSelection();
void selectNext();
void selectPrevious();
bool isSelected(int base, int offset);
// Data Management
void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = "", SortBy::t sortFn = SortBy::AsText);
void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = "");
void setRowCount(int count);
void deleteAllColumns();
void setCellContent(int r, int c, QString s);
@ -61,16 +60,15 @@ private:
class ColumnCompare
{
public:
ColumnCompare(int col, bool greater, SortBy::t fn)
ColumnCompare(int col, bool greater)
{
mCol = col;
mGreater = greater;
mSortFn = fn;
}
inline bool operator()(const QList<QString> & a, const QList<QString> & b) const
{
bool less = mSortFn(a.at(mCol), b.at(mCol));
bool less = QString::compare(a.at(mCol), b.at(mCol), Qt::CaseInsensitive) < 0;
if(mGreater)
return !less;
return less;
@ -78,7 +76,6 @@ private:
private:
int mCol;
int mGreater;
SortBy::t mSortFn;
};
enum GuiState_t {NoState, MultiRowsSelectionState};

View File

@ -3,9 +3,7 @@
#include "QBeaEngine.h"
#include "main.h"
#include "Exports.h"
#include <qmetaobject.h>
#define MEASURE_LATENCY_EVENT ((QEvent::Type)(QEvent::User + 42))
/************************************************************************************
Global Variables
************************************************************************************/
@ -23,49 +21,11 @@ Bridge::Bridge(QObject* parent) : QObject(parent)
bridgeResult = 0;
hasBridgeResult = false;
dbgStopped = false;
qRegisterMetaType <uint32_t>("uint32_t");
connect(this, SIGNAL(measureLatency(uint32_t)),
this, SLOT(measureLatencySlot(uint32_t)), Qt::ConnectionType::QueuedConnection);
latencyThread = std::thread([this]
{
while(mBridgeMutex)
{
std::unique_lock<std::mutex> guard(latencyLock);
latencyLastRequest = GetTickCount();
// We can't use a normal signal/slot for this since we can't se the priority on that.
// If we don't have the low priority set; this gets scheduled ahead of UI events so
// we won't get accurate measurements.
QCoreApplication::postEvent(this, new QEvent(MEASURE_LATENCY_EVENT), Qt::LowEventPriority);
std::this_thread::sleep_for(std::chrono::milliseconds(40));
latencyCV.wait(guard, [this] { return latencyLastRequest < latencyLastResponse; });
}
});
}
void Bridge::customEvent(QEvent* ev)
{
if(ev->type() == MEASURE_LATENCY_EVENT)
{
std::unique_lock<std::mutex> guard(latencyLock);
latencyLastResponse = GetTickCount();
// TickCount can overflow; just reset lastrequest
if(latencyLastResponse < latencyLastRequest)
latencyLastRequest = 0;
latencyMs = latencyLastResponse - latencyLastRequest;
latencyCV.notify_one();
}
}
Bridge::~Bridge()
{
delete mBridgeMutex;
mBridgeMutex = 0;
latencyCV.notify_all();
latencyThread.join();
}
void Bridge::CopyToClipboard(const QString & text)
@ -625,24 +585,6 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
/************************************************************************************
Exported Functions
************************************************************************************/
__declspec(dllexport) uint32 _gui_messagelatency()
{
uint32 latencyLastRequest = Bridge::getBridge()->latencyLastRequest;
uint32 latencyLastResponse = Bridge::getBridge()->latencyLastResponse;
uint32 latencyMs = Bridge::getBridge()->latencyMs;
// Indicates a pending request
if(latencyLastResponse > latencyLastRequest)
{
// If the current wait time exceeds the last measurement, use that instead.
// this makes sure that if the pipeline is super stalled all of a sudden,
// the measurement is still somewhat accurate; although it would still be
// a floor on the actual latency.
uint32 currentWait = GetTickCount() - latencyLastRequest;
latencyMs = std::max(latencyMs, currentWait);
}
return latencyMs;
}
__declspec(dllexport) int _gui_guiinit(int argc, char* argv[])
{
return main(argc, argv);

View File

@ -8,18 +8,12 @@
#include "Imports.h"
#include "ReferenceManager.h"
#include "BridgeResult.h"
#include <thread>
#include <condition_variable>
#include <mutex>
class Bridge : public QObject
{
Q_OBJECT
friend class BridgeResult;
std::thread latencyThread;
std::mutex latencyLock;
std::condition_variable latencyCV;
public:
explicit Bridge(QObject* parent = 0);
@ -28,10 +22,6 @@ public:
static Bridge* getBridge();
static void initBridge();
uint32 latencyMs = 0;
uint32 latencyLastRequest = 0;
uint32 latencyLastResponse = 0;
// Message processing function
void* processMessage(GUIMSG type, void* param1, void* param2);
@ -51,9 +41,6 @@ public:
QWidget* scriptView;
ReferenceManager* referenceManager;
protected:
virtual void customEvent(QEvent* event) override;
signals:
void disassembleAt(dsint va, dsint eip);
void repaintGui();

View File

@ -8,10 +8,10 @@
************************************************************************************/
#ifdef BUILD_LIB
extern "C" __declspec(dllexport) uint32 _gui_messagelatency();
extern "C" __declspec(dllexport) int _gui_guiinit(int argc, char* argv[]);
extern "C" __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* param2);
extern "C" __declspec(dllexport) void _gui_sendmessageasync(GUIMSG type, void* param1, void* param2);
#endif
#endif // EXPORTS_H

View File

@ -16,8 +16,6 @@ CommandLineEdit::CommandLineEdit(QWidget* parent)
mCompleterModel = (QStringListModel*)mCompleter->model();
this->setCompleter(mCompleter);
loadSettings("CommandLine");
//Setup signals & slots
connect(mCompleter, SIGNAL(activated(const QString &)), this, SLOT(clear()), Qt::QueuedConnection);
connect(this, SIGNAL(textEdited(QString)), this, SLOT(autoCompleteUpdate(QString)));
@ -29,11 +27,6 @@ CommandLineEdit::CommandLineEdit(QWidget* parent)
connect(mCmdScriptType, SIGNAL(currentIndexChanged(int)), this, SLOT(scriptTypeChanged(int)));
}
CommandLineEdit::~CommandLineEdit()
{
saveSettings("CommandLine");
}
void CommandLineEdit::keyPressEvent(QKeyEvent* event)
{
if(event->type() == QEvent::KeyPress && event->key() == Qt::Key_Tab)

View File

@ -14,8 +14,6 @@ class CommandLineEdit : public HistoryLineEdit
public:
explicit CommandLineEdit(QWidget* parent = 0);
~CommandLineEdit();
void keyPressEvent(QKeyEvent* event);
bool focusNextPrevChild(bool next);

View File

@ -103,10 +103,7 @@ void LogView::addMsgToLogSlot(QString msg)
return;
if(this->document()->characterCount() > 10000 * 100) //limit the log to ~100mb
this->clear();
// This sets the cursor to the end for the next insert
this->moveCursor(QTextCursor::End);
this->insertPlainText(msg);
// This sets the cursor to the end to display the new text
this->moveCursor(QTextCursor::End);
}

View File

@ -341,8 +341,9 @@ void MainWindow::setupStatusBar()
ui->statusBar->addPermanentWidget(mLastLogLabel, 1);
// Time wasted counter
mTimeWastedCounter = new TimeWastedCounter(this);
ui->statusBar->addPermanentWidget(mTimeWastedCounter);
QLabel* timeWastedLabel = new QLabel(this);
ui->statusBar->addPermanentWidget(timeWastedLabel);
mTimeWastedCounter = new TimeWastedCounter(this, timeWastedLabel);
}
void MainWindow::closeEvent(QCloseEvent* event)

View File

@ -25,7 +25,6 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
mModuleList = new SearchListView();
mModuleList->mSearchStartCol = 1;
int charwidth = mModuleList->mList->getCharWidth();
mModuleList->mList->enableMultiSelection(true);
mModuleList->mList->setCipBase(true);
mModuleList->mList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, tr("Base"), false);
mModuleList->mList->addColumnAt(300, tr("Module"), true);
@ -36,14 +35,12 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
mModuleList->mSearchList->addColumnAt(charwidth * 8, tr("Party"), false);
// Setup symbol list
mSearchListView->mList->enableMultiSelection(true);
mSearchListView->mList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, tr("Address"), true);
mSearchListView->mList->addColumnAt(charwidth * 6 + 8, tr("Type"), true);
mSearchListView->mList->addColumnAt(charwidth * 80, tr("Symbol"), true);
mSearchListView->mList->addColumnAt(2000, tr("Symbol (undecorated)"), true);
// Setup search list
mSearchListView->mSearchList->enableMultiSelection(true);
mSearchListView->mSearchList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, tr("Address"), true);
mSearchListView->mSearchList->addColumnAt(charwidth * 6 + 8, tr("Type"), true);
mSearchListView->mSearchList->addColumnAt(charwidth * 80, tr("Symbol"), true);
@ -226,22 +223,15 @@ void SymbolView::cbSymbolEnum(SYMBOLINFO* symbol, void* user)
void SymbolView::moduleSelectionChanged(int index)
{
setUpdatesEnabled(false);
QString mod = mModuleList->mCurList->getCellContent(index, 1);
if(!mModuleBaseList.count(mod))
return;
mSearchListView->mList->setRowCount(0);
for(auto index : mModuleList->mCurList->getSelection())
{
QString mod = mModuleList->mCurList->getCellContent(index, 1);
if(!mModuleBaseList.count(mod))
continue;
DbgSymbolEnumFromCache(mModuleBaseList[mod], cbSymbolEnum, mSearchListView->mList);
}
DbgSymbolEnumFromCache(mModuleBaseList[mod], cbSymbolEnum, mSearchListView->mList);
mSearchListView->mList->reloadData();
mSearchListView->mList->setSingleSelection(0);
mSearchListView->mList->setTableOffset(0);
mSearchListView->mSearchBox->setText("");
setUpdatesEnabled(true);
}
void SymbolView::updateSymbolList(int module_count, SYMBOLMODULEINFO* modules)
@ -400,33 +390,27 @@ void SymbolView::toggleBreakpoint()
if(!mSearchListView->mCurList->getRowCount())
return;
QString addrText = mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0);
duint wVA;
if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA))
return;
auto selection = mSearchListView->mCurList->getSelection();
if(!DbgMemIsValidReadPtr(wVA))
return;
for(auto selectedIdx : selection)
BPXTYPE wBpType = DbgGetBpxTypeAt(wVA);
QString wCmd;
if((wBpType & bp_normal) == bp_normal)
{
QString addrText = mSearchListView->mCurList->getCellContent(selectedIdx, 0);
duint wVA;
if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA))
return;
if(!DbgMemIsValidReadPtr(wVA))
return;
BPXTYPE wBpType = DbgGetBpxTypeAt(wVA);
QString wCmd;
if((wBpType & bp_normal) == bp_normal)
{
wCmd = "bc " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
else
{
wCmd = "bp " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
DbgCmdExec(wCmd.toUtf8().constData());
wCmd = "bc " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
else
{
wCmd = "bp " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
DbgCmdExec(wCmd.toUtf8().constData());
}
void SymbolView::toggleBookmark()

View File

@ -189,16 +189,16 @@ void ThreadView::setupContextMenu()
ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
{
int charwidth = getCharWidth();
addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, tr("Number"), false, "", SortBy::AsInt);
addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, tr("ID"), false, "", SortBy::AsHex);
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("Entry"), false, "", SortBy::AsHex);
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("TEB"), false, "", SortBy::AsHex);
addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, tr("Number"), false);
addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, tr("ID"), false);
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("Entry"), false);
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("TEB"), false);
#ifdef _WIN64
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("RIP"), false, "", SortBy::AsHex);
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("RIP"), false);
#else
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("EIP"), false, "", SortBy::AsHex);
addColumnAt(8 + charwidth * sizeof(duint) * 2, tr("EIP"), false);
#endif //_WIN64
addColumnAt(8 + charwidth * 14, tr("Suspend Count"), false, "", SortBy::AsInt);
addColumnAt(8 + charwidth * 14, tr("Suspend Count"), false);
addColumnAt(8 + charwidth * 12, tr("Priority"), false);
addColumnAt(8 + charwidth * 12, tr("Wait Reason"), false);
addColumnAt(8 + charwidth * 11, tr("Last Error"), false);

View File

@ -1,61 +1,20 @@
#include "TimeWastedCounter.h"
#include "Bridge.h"
TimeWastedCounter::TimeWastedCounter(QWidget* parent)
: QLabel(parent)
TimeWastedCounter::TimeWastedCounter(QObject* parent, QLabel* label)
: QObject(parent), mLabel(label)
{
setFrameStyle(QFrame::Sunken | QFrame::Panel); //sunken style
setStyleSheet("QLabel { background-color : #c0c0c0; }");
mLastTime = GetTickCount64();
BridgeSettingGetUint("TimeWastedCounter", "CounterMode", (duint*)&mCounterMode);
mLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); //sunken style
mLabel->setStyleSheet("QLabel { background-color : #c0c0c0; }");
connect(Bridge::getBridge(), SIGNAL(updateTimeWastedCounter()), this, SLOT(updateTimeWastedCounter()));
}
void TimeWastedCounter::mousePressEvent(QMouseEvent*)
{
mCounterMode = (TimeWastedCounterMode::t)((int)mCounterMode + 1);
if(mCounterMode >= TimeWastedCounterMode::SIZE)
{
mCounterMode = (TimeWastedCounterMode::t)0;
}
BridgeSettingSetUint("TimeWastedCounter", "CounterMode", mCounterMode);
}
void TimeWastedCounter::updateTimeWastedCounter()
{
uint64 totalDbgEvents = DbgFunctions()->GetDbgEvents();
uint64 dbgEvents = totalDbgEvents - mLastEventCount;
mLastEventCount = totalDbgEvents;
uint64 time = GetTickCount64();
uint64 timeDelta = time - mLastTime;
mLastTime = time;
duint dbgEvents = DbgFunctions()->GetDbgEvents();
if(dbgEvents > 4)
{
QString msg = "";
switch(mCounterMode)
{
default:
case TimeWastedCounterMode::EventsDelta:
msg = tr("%1 events in %2ms (%3ms)")
.arg(dbgEvents)
.arg(timeDelta);
break;
case TimeWastedCounterMode::EventsTotal:
msg = tr("%1(+%2) total events (%3ms)")
.arg(totalDbgEvents)
.arg(dbgEvents);
break;
case TimeWastedCounterMode::EventsHertz:
if(timeDelta == 0) // Keeps the old message
return;
msg = tr("%1 events/sec (%3ms)")
.arg(dbgEvents * 1000 / timeDelta);
break;
}
msg = msg.arg(Bridge::getBridge()->latencyMs);
setText(msg);
mLabel->setText(tr("%1 events/s").arg(dbgEvents));
}
else
{
@ -64,6 +23,6 @@ void TimeWastedCounter::updateTimeWastedCounter()
int hours = (timeWasted / (60 * 60)) % 24;
int minutes = (timeWasted / 60) % 60;
int seconds = timeWasted % 60;
setText(tr("Time Wasted Debugging:") + QString().sprintf(" %d:%02d:%02d:%02d", days, hours, minutes, seconds));
mLabel->setText(tr("Time Wasted Debugging:") + QString().sprintf(" %d:%02d:%02d:%02d", days, hours, minutes, seconds));
}
}

View File

@ -3,33 +3,18 @@
#include <QObject>
#include <QLabel>
#include <stdint.h>
class TimeWastedCounter : public QLabel
class TimeWastedCounter : public QObject
{
Q_OBJECT
public:
explicit TimeWastedCounter(QWidget* parent);
explicit TimeWastedCounter(QObject* parent, QLabel* label);
private slots:
void updateTimeWastedCounter();
protected:
void mousePressEvent(QMouseEvent* event);
private:
struct TimeWastedCounterMode
{
enum t
{
EventsDelta = 0,
EventsTotal,
EventsHertz,
SIZE
};
};
TimeWastedCounterMode::t mCounterMode = TimeWastedCounterMode::EventsDelta;
uint64_t mLastEventCount = 0;
uint64_t mLastTime = 0;
private:
QLabel* mLabel;
};
#endif // TIMEWASTEDCOUNTER_H