DBG + GUI: don't try to set breakpoints on invalid TLS callbacks + added time wasted counter + added version number in menu bar

This commit is contained in:
Mr. eXoDia 2015-08-08 15:55:59 +02:00
parent f0565fb57b
commit 61fa77d3ac
11 changed files with 139 additions and 11 deletions

View File

@ -805,6 +805,11 @@ BRIDGE_IMPEXP bool DbgIsRunning()
return !DbgIsRunLocked();
}
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter()
{
return _dbg_sendmessage(DBG_GET_TIME_WASTED_COUNTER, nullptr, nullptr);
}
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
{
_gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip);
@ -1195,6 +1200,11 @@ BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread)
_gui_sendmessage(GUI_EXECUTE_ON_GUI_THREAD, cbGuiThread, nullptr);
}
BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter()
{
_gui_sendmessage(GUI_UPDATE_TIME_WASTED_COUNTER, nullptr, nullptr);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
hInst = hinstDLL;

View File

@ -174,7 +174,8 @@ typedef enum
DBG_WIN_EVENT, // param1=MSG* message, param2=long* result
DBG_WIN_EVENT_GLOBAL, // param1=MSG* message, param2=unused
DBG_INITIALIZE_LOCKS, // param1=unused, param2=unused
DBG_DEINITIALIZE_LOCKS // param1=unused, param2=unused
DBG_DEINITIALIZE_LOCKS, // param1=unused, param2=unused
DBG_GET_TIME_WASTED_COUNTER // param1=unused, param2=unused
} DBGMSG;
typedef enum
@ -691,6 +692,7 @@ BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions();
BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result);
BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message);
BRIDGE_IMPEXP bool DbgIsRunning();
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter();
//Gui defines
#define GUI_PLUGIN_MENU 0
@ -772,7 +774,8 @@ typedef enum
GUI_ADD_QWIDGET_TAB, // param1=QWidget*, param2=unused
GUI_SHOW_QWIDGET_TAB, // param1=QWidget*, param2=unused
GUI_CLOSE_QWIDGET_TAB, // param1=QWidget*, param2=unused
GUI_EXECUTE_ON_GUI_THREAD // param1=GUICALLBACK, param2=unused
GUI_EXECUTE_ON_GUI_THREAD, // param1=GUICALLBACK, param2=unused
GUI_UPDATE_TIME_WASTED_COUNTER // param1=unused, param2=unused
} GUIMSG;
//GUI Typedefs
@ -866,6 +869,7 @@ BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget);
BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget);
BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget);
BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread);
BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter();
#ifdef __cplusplus
}

View File

@ -1006,6 +1006,9 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
SectionLockerGlobal::Deinitialize();
}
break;
case DBG_GET_TIME_WASTED_COUNTER:
return dbggettimewastedcounter();
}
return 0;
}

View File

@ -39,7 +39,10 @@ static HANDLE hEvent = 0;
static HANDLE hProcess = 0;
static HANDLE hMemMapThread = 0;
static bool bStopMemMapThread = false;
static HANDLE hTimeWastedCounterThread = 0;
static bool bStopTimeWastedCounterThread = false;
static String lastDebugText;
static uint timeWastedDebugging = 0;
char szFileName[MAX_PATH] = "";
char szSymbolCachePath[MAX_PATH] = "";
char sqlitedb[deflen] = "";
@ -72,17 +75,43 @@ static DWORD WINAPI memMapThread(void* ptr)
return 0;
}
static DWORD WINAPI timeWastedCounterThread(void* ptr)
{
if (!BridgeSettingGetUint("Engine", "TimeWastedDebugging", &timeWastedDebugging))
timeWastedDebugging = 0;
GuiUpdateTimeWastedCounter();
while (!bStopTimeWastedCounterThread)
{
while (!DbgIsDebugging())
{
if (bStopTimeWastedCounterThread)
break;
Sleep(1);
}
if (bStopTimeWastedCounterThread)
break;
timeWastedDebugging++;
GuiUpdateTimeWastedCounter();
Sleep(1000);
}
BridgeSettingSetUint("Engine", "TimeWastedDebugging", timeWastedDebugging);
return 0;
}
void dbginit()
{
ExceptionCodeInit();
ErrorCodeInit();
hMemMapThread = CreateThread(0, 0, memMapThread, 0, 0, 0);
hMemMapThread = CreateThread(nullptr, 0, memMapThread, nullptr, 0, nullptr);
hTimeWastedCounterThread = CreateThread(nullptr, 0, timeWastedCounterThread, nullptr, 0, nullptr);
}
void dbgstop()
{
bStopMemMapThread = true;
bStopTimeWastedCounterThread = true;
WaitForThreadTermination(hMemMapThread);
WaitForThreadTermination(hTimeWastedCounterThread);
}
SIZE_T dbggetprivateusage(HANDLE hProcess, bool update)
@ -101,6 +130,11 @@ uint dbgdebuggedbase()
return pDebuggedBase;
}
uint dbggettimewastedcounter()
{
return timeWastedDebugging;
}
bool dbgisrunning()
{
return !waitislocked(WAITID_RUN);
@ -675,11 +709,20 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
else
{
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE);
int invalidCount = 0;
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
{
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + pDebuggedBase, i + 1);
cmddirectexec(dbggetcommandlist(), command);
uint callbackVA = TLSCallBacks()[i] - ImageBase + pDebuggedBase;
if (MemIsValidReadPtr(callbackVA))
{
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
cmddirectexec(dbggetcommandlist(), command);
}
else
invalidCount++;
}
if (invalidCount)
dprintf("%d invalid TLS callback addresses...\n", invalidCount);
}
}
}
@ -871,14 +914,23 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
else
{
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE);
int invalidCount = 0;
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
{
if(bIsDebuggingThis)
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1);
uint callbackVA = TLSCallBacks()[i] - ImageBase + (uint)base;
if (MemIsValidReadPtr(callbackVA))
{
if (bIsDebuggingThis)
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
else
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", callbackVA, i + 1, modname);
cmddirectexec(dbggetcommandlist(), command);
}
else
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1, modname);
cmddirectexec(dbggetcommandlist(), command);
invalidCount++;
}
if (invalidCount)
dprintf("%s invalid TLS callback addresses...\n", invalidCount);
}
}
}

View File

@ -77,6 +77,7 @@ SIZE_T dbggetprivateusage(HANDLE hProcess, bool update = false);
void dbginit();
void dbgstop();
uint dbgdebuggedbase();
uint dbggettimewastedcounter();
bool dbgisrunning();
bool dbgisdll();
void dbgsetattachevent(HANDLE handle);

View File

@ -485,6 +485,10 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
GuiAddLogMessage(QString().sprintf("thread id (bridge) %X\n", GetCurrentThreadId()).toUtf8().constData());
emit executeOnGuiThread(param1);
break;
case GUI_UPDATE_TIME_WASTED_COUNTER:
emit updateTimeWastedCounter();
break;
}
return nullptr;
}

View File

@ -109,6 +109,7 @@ signals:
void showQWidgetTab(QWidget* qWidget);
void closeQWidgetTab(QWidget* qWidget);
void executeOnGuiThread(void* cbGuiThread);
void updateTimeWastedCounter();
private:
QMutex* mBridgeMutex;

View File

@ -12,11 +12,23 @@
#include "ShortcutsDialog.h"
#include "AttachDialog.h"
#include "LineEditDialog.h"
#include "TimeWastedCounter.h"
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
//build information
QString buildText = QString().sprintf("v%d, "__DATE__, BridgeGetDbgVersion());
QAction* buildInfo = new QAction(buildText, this);
buildInfo->setEnabled(false);
ui->menuBar->addAction(buildInfo);
//time wasted counter
QAction* timeWastedLabel = new QAction(this);
ui->menuBar->addAction(timeWastedLabel);
TimeWastedCounter* timeWastedCounter = new TimeWastedCounter(this, timeWastedLabel);
//setup bridge signals
connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString)));
connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString)));

View File

@ -0,0 +1,19 @@
#include "TimeWastedCounter.h"
#include "Bridge.h"
TimeWastedCounter::TimeWastedCounter(QObject* parent, QAction* label)
: QObject(parent), mLabel(label)
{
mLabel->setEnabled(false);
connect(Bridge::getBridge(), SIGNAL(updateTimeWastedCounter()), this, SLOT(updateTimeWastedCounter()));
}
void TimeWastedCounter::updateTimeWastedCounter()
{
duint timeWasted = DbgGetTimeWastedCounter();
int days = timeWasted / (60 * 60 * 24);
int hours = (timeWasted / (60 * 60)) % 24;
int minutes = (timeWasted / 60) % 60;
int seconds = timeWasted % 60;
mLabel->setText(QString().sprintf("Time Wasted Debugging: %d:%02d:%02d:%02d", days, hours, minutes, seconds));
}

View File

@ -0,0 +1,20 @@
#ifndef TIMEWASTEDCOUNTER_H
#define TIMEWASTEDCOUNTER_H
#include <QObject>
#include <QAction>
class TimeWastedCounter : public QObject
{
Q_OBJECT
public:
explicit TimeWastedCounter(QObject* parent, QAction* label);
private slots:
void updateTimeWastedCounter();
private:
QAction* mLabel;
};
#endif // TIMEWASTEDCOUNTER_H

View File

@ -92,7 +92,8 @@ SOURCES += \
Src/Gui/SourceViewerManager.cpp \
Src/Gui/SourceView.cpp \
Src/Utils/ValidateExpressionThread.cpp \
Src/Utils/MainWindowCloseThread.cpp
Src/Utils/MainWindowCloseThread.cpp \
Src/Gui/TimeWastedCounter.cpp
HEADERS += \
@ -164,7 +165,8 @@ HEADERS += \
Src/Gui/SourceView.h \
Src/Utils/StringUtil.h \
Src/Utils/ValidateExpressionThread.h \
Src/Utils/MainWindowCloseThread.h
Src/Utils/MainWindowCloseThread.h \
Src/Gui/TimeWastedCounter.h
INCLUDEPATH += \