Merge pull request #7 from GleeBug/threads

process & thread housekeeping functionality
This commit is contained in:
strongbit 2015-03-25 20:41:21 +00:00
commit ed7d8e453f
10 changed files with 113 additions and 56 deletions

View File

@ -1,20 +0,0 @@
#ifndef _DEBUGGER_DATA_H
#define _DEBUGGER_DATA_H
#include "_global.h"
namespace GleeBug
{
/**
\brief Process information structure.
*/
struct ProcessInfo
{
HANDLE hProcess;
HANDLE hThread;
DWORD ProcessId;
DWORD MainThreadId;
};
}
#endif //_DEBUGGER_DATA_H

View File

@ -4,26 +4,47 @@ namespace GleeBug
{
void Debugger::createProcessEvent(CREATE_PROCESS_DEBUG_INFO* createProcess)
{
//process housekeeping
ProcessInfo process(createProcess->hProcess,
createProcess->hThread,
_debugEvent.dwProcessId,
_debugEvent.dwThreadId);
_processes.insert({ process.dwProcessId, process });
//call the callback
cbCreateProcessEvent(createProcess);
}
void Debugger::exitProcessEvent(EXIT_PROCESS_DEBUG_INFO* exitProcess)
{
if (_debugEvent.dwProcessId == _mainProcess.ProcessId)
{
//check if the terminated process is the main debuggee
if (_debugEvent.dwProcessId == _mainProcess.dwProcessId)
_breakDebugger = true;
}
//call the callback
cbExitProcessEvent(exitProcess);
//process housekeeping
_processes.erase(_debugEvent.dwProcessId);
}
void Debugger::createThreadEvent(CREATE_THREAD_DEBUG_INFO* createThread)
{
//thread housekeeping
ThreadInfo thread(_debugEvent.dwThreadId, createThread->hThread, createThread->lpThreadLocalBase, createThread->lpStartAddress);
_processes[_debugEvent.dwProcessId].threads.insert({ thread.dwThreadId, thread });
//call the callback
cbCreateThreadEvent(createThread);
}
void Debugger::exitThreadEvent(EXIT_THREAD_DEBUG_INFO* exitThread)
{
//call the callback
cbExitThreadEvent(exitThread);
//thread housekeeping
_processes[_debugEvent.dwProcessId].threads.erase(_debugEvent.dwThreadId);
}
void Debugger::loadDllEvent(LOAD_DLL_DEBUG_INFO* loadDll)

View File

@ -0,0 +1,36 @@
#ifndef _DEBUGGER_PROCESS_H
#define _DEBUGGER_PROCESS_H
#include "_global.h"
#include "Debugger.Thread.h"
namespace GleeBug
{
/**
\brief Process information structure.
*/
struct ProcessInfo
{
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwMainThreadId;
ThreadMap threads;
ProcessInfo() {} //fixes a 'no default constructor available' error
ProcessInfo(HANDLE hProcess, HANDLE hThread, DWORD dwProcessId, DWORD dwMainThreadId)
{
this->hProcess = hProcess;
this->hThread = hThread;
this->dwProcessId = dwProcessId;
this->dwMainThreadId = dwMainThreadId;
this->threads.clear();
}
};
typedef std::map<DWORD, ProcessInfo> ProcessMap;
}
#endif //_DEBUGGER_PROCESS_H

30
GleeBug/Debugger.Thread.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _DEBUGGER_THREADS_H
#define _DEBUGGER_THREADS_H
#include "_global.h"
namespace GleeBug
{
/**
\brief Thread information structure.
*/
struct ThreadInfo
{
DWORD dwThreadId;
HANDLE hThread;
ULONG_PTR lpThreadLocalBase;
ULONG_PTR lpStartAddress;
ThreadInfo(DWORD dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress)
{
this->dwThreadId = dwThreadId;
this->hThread = hThread;
this->lpThreadLocalBase = (ULONG_PTR)lpThreadLocalBase;
this->lpStartAddress = (ULONG_PTR)lpStartAddress;
}
};
typedef std::map<DWORD, ThreadInfo> ThreadMap;
};
#endif //_DEBUGGER_THREADS_H

View File

@ -4,6 +4,7 @@ namespace GleeBug
{
Debugger::Debugger()
{
_processes.clear();
}
bool Debugger::Init(const wchar_t* szFilePath,
@ -12,8 +13,6 @@ namespace GleeBug
{
STARTUPINFOW si;
memset(&si, 0, sizeof(si));
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
const wchar_t* szFileNameCreateProcess;
wchar_t* szCommandLineCreateProcess;
if (szCommandLine == NULL || !wcslen(szCommandLine))
@ -29,7 +28,7 @@ namespace GleeBug
szFileNameCreateProcess = 0;
}
if (!CreateProcessW(szFileNameCreateProcess,
return !!CreateProcessW(szFileNameCreateProcess,
szCommandLineCreateProcess,
NULL,
NULL,
@ -38,15 +37,7 @@ namespace GleeBug
NULL,
szCurrentDirectory,
&si,
&pi))
{
return false;
}
_mainProcess.hProcess = pi.hProcess;
_mainProcess.hThread = pi.hThread;
_mainProcess.ProcessId = pi.dwProcessId;
_mainProcess.MainThreadId = pi.dwThreadId;
return true;
&_mainProcess);
}
bool Debugger::Stop()
@ -56,11 +47,6 @@ namespace GleeBug
bool Debugger::Detach()
{
return !!DebugActiveProcessStop(_mainProcess.ProcessId);
}
const ProcessInfo & Debugger::GetMainProcess()
{
return _mainProcess;
return !!DebugActiveProcessStop(_mainProcess.dwProcessId);
}
};

View File

@ -2,7 +2,7 @@
#define _DEBUGGER_H
#include "_global.h"
#include "Debugger.Data.h"
#include "Debugger.Process.h"
namespace GleeBug
{
@ -45,12 +45,6 @@ namespace GleeBug
*/
void Start();
/**
\brief Gets main process info.
\return The main process info.
*/
const ProcessInfo & GetMainProcess();
protected:
/**
\brief Process creation debug event callback. Provide an implementation to use this callback.
@ -129,12 +123,11 @@ namespace GleeBug
virtual void debugStringEvent(OUTPUT_DEBUG_STRING_INFO* debugString);
virtual void ripEvent(RIP_INFO* rip);
ProcessInfo _mainProcess;
PROCESS_INFORMATION _mainProcess;
DWORD _continueStatus;
bool _breakDebugger;
DEBUG_EVENT _debugEvent;
ProcessMap _processes;
};
};

View File

@ -139,8 +139,9 @@
<ClCompile Include="_global.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Debugger.Data.h" />
<ClInclude Include="Debugger.Process.h" />
<ClInclude Include="Debugger.h" />
<ClInclude Include="Debugger.Thread.h" />
<ClInclude Include="_global.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -29,10 +29,13 @@
<ClInclude Include="_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.Data.h">
<ClInclude Include="Debugger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.h">
<ClInclude Include="Debugger.Process.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.Thread.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@ -3,6 +3,9 @@
#include <cstdio>
#include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <windows.h>
#endif //_GLOBAL_H

View File

@ -3,9 +3,13 @@
int main()
{
wchar_t szFilePath[256] = L"c:\\CodeBlocks\\arma_cert_bin_info\\bin\\arma_cert_bin_info.exe";
#ifdef _WIN64
wchar_t szFilePath[256] = L"c:\\test64.exe";
#else //x86
wchar_t szFilePath[256] = L"c:\\test32.exe";
#endif //_WIN64
wchar_t szCommandLine[256] = L"";
wchar_t szCurrentDir[256] = L"c:\\CodeBlocks\\arma_cert_bin_info\\bin";
wchar_t szCurrentDir[256] = L"c:\\";
MyDebugger dbg;
if (dbg.Init(szFilePath, szCommandLine, szCurrentDir))
{