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(); return !DbgIsRunLocked();
} }
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter()
{
return _dbg_sendmessage(DBG_GET_TIME_WASTED_COUNTER, nullptr, nullptr);
}
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip) BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
{ {
_gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)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); _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) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {
hInst = hinstDLL; hInst = hinstDLL;

View File

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

View File

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

View File

@ -39,7 +39,10 @@ static HANDLE hEvent = 0;
static HANDLE hProcess = 0; static HANDLE hProcess = 0;
static HANDLE hMemMapThread = 0; static HANDLE hMemMapThread = 0;
static bool bStopMemMapThread = false; static bool bStopMemMapThread = false;
static HANDLE hTimeWastedCounterThread = 0;
static bool bStopTimeWastedCounterThread = false;
static String lastDebugText; static String lastDebugText;
static uint timeWastedDebugging = 0;
char szFileName[MAX_PATH] = ""; char szFileName[MAX_PATH] = "";
char szSymbolCachePath[MAX_PATH] = ""; char szSymbolCachePath[MAX_PATH] = "";
char sqlitedb[deflen] = ""; char sqlitedb[deflen] = "";
@ -72,17 +75,43 @@ static DWORD WINAPI memMapThread(void* ptr)
return 0; 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() void dbginit()
{ {
ExceptionCodeInit(); ExceptionCodeInit();
ErrorCodeInit(); 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() void dbgstop()
{ {
bStopMemMapThread = true; bStopMemMapThread = true;
bStopTimeWastedCounterThread = true;
WaitForThreadTermination(hMemMapThread); WaitForThreadTermination(hMemMapThread);
WaitForThreadTermination(hTimeWastedCounterThread);
} }
SIZE_T dbggetprivateusage(HANDLE hProcess, bool update) SIZE_T dbggetprivateusage(HANDLE hProcess, bool update)
@ -101,6 +130,11 @@ uint dbgdebuggedbase()
return pDebuggedBase; return pDebuggedBase;
} }
uint dbggettimewastedcounter()
{
return timeWastedDebugging;
}
bool dbgisrunning() bool dbgisrunning()
{ {
return !waitislocked(WAITID_RUN); return !waitislocked(WAITID_RUN);
@ -675,11 +709,20 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
else else
{ {
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE); uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE);
int invalidCount = 0;
for(unsigned int i = 0; i < NumberOfCallBacks; i++) for(unsigned int i = 0; i < NumberOfCallBacks; i++)
{ {
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + pDebuggedBase, i + 1); uint callbackVA = TLSCallBacks()[i] - ImageBase + pDebuggedBase;
if (MemIsValidReadPtr(callbackVA))
{
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
cmddirectexec(dbggetcommandlist(), command); 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 else
{ {
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE); uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE);
int invalidCount = 0;
for(unsigned int i = 0; i < NumberOfCallBacks; i++) for(unsigned int i = 0; i < NumberOfCallBacks; i++)
{ {
if(bIsDebuggingThis) uint callbackVA = TLSCallBacks()[i] - ImageBase + (uint)base;
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1); if (MemIsValidReadPtr(callbackVA))
{
if (bIsDebuggingThis)
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
else else
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1, modname); sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", callbackVA, i + 1, modname);
cmddirectexec(dbggetcommandlist(), command); cmddirectexec(dbggetcommandlist(), command);
} }
else
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 dbginit();
void dbgstop(); void dbgstop();
uint dbgdebuggedbase(); uint dbgdebuggedbase();
uint dbggettimewastedcounter();
bool dbgisrunning(); bool dbgisrunning();
bool dbgisdll(); bool dbgisdll();
void dbgsetattachevent(HANDLE handle); 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()); GuiAddLogMessage(QString().sprintf("thread id (bridge) %X\n", GetCurrentThreadId()).toUtf8().constData());
emit executeOnGuiThread(param1); emit executeOnGuiThread(param1);
break; break;
case GUI_UPDATE_TIME_WASTED_COUNTER:
emit updateTimeWastedCounter();
break;
} }
return nullptr; return nullptr;
} }

View File

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

View File

@ -12,11 +12,23 @@
#include "ShortcutsDialog.h" #include "ShortcutsDialog.h"
#include "AttachDialog.h" #include "AttachDialog.h"
#include "LineEditDialog.h" #include "LineEditDialog.h"
#include "TimeWastedCounter.h"
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{ {
ui->setupUi(this); 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 //setup bridge signals
connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString))); connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString)));
connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(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/SourceViewerManager.cpp \
Src/Gui/SourceView.cpp \ Src/Gui/SourceView.cpp \
Src/Utils/ValidateExpressionThread.cpp \ Src/Utils/ValidateExpressionThread.cpp \
Src/Utils/MainWindowCloseThread.cpp Src/Utils/MainWindowCloseThread.cpp \
Src/Gui/TimeWastedCounter.cpp
HEADERS += \ HEADERS += \
@ -164,7 +165,8 @@ HEADERS += \
Src/Gui/SourceView.h \ Src/Gui/SourceView.h \
Src/Utils/StringUtil.h \ Src/Utils/StringUtil.h \
Src/Utils/ValidateExpressionThread.h \ Src/Utils/ValidateExpressionThread.h \
Src/Utils/MainWindowCloseThread.h Src/Utils/MainWindowCloseThread.h \
Src/Gui/TimeWastedCounter.h
INCLUDEPATH += \ INCLUDEPATH += \