Files
qt-creator/tests/manual/cdbdebugger/windbgthread.cpp
2009-02-09 11:37:19 +01:00

151 lines
3.2 KiB
C++

#include "windbgthread.h"
#include <QDebug>
#define DBGHELP_TRANSLATE_TCHAR
#include <Dbghelp.h>
WinDbgThread::WinDbgThread(QObject* parent)
: QThread(parent),
m_state(Idle)
{
}
WinDbgThread::~WinDbgThread()
{
stopProcess();
}
void WinDbgThread::startProcess(const QString& filename)
{
stopProcess();
m_bOwnsProcess = true;
m_processFileName = filename;
m_pi.dwProcessId = 0;
QThread::start();
}
void WinDbgThread::stopProcess()
{
if (!QThread::isRunning())
return;
switch (m_state)
{
case ProcessRunning:
if (m_bOwnsProcess) {
m_bOwnsProcess = false; // don't terminate in the loop again
TerminateProcess(m_pi.hProcess, 0);
}
// don't break here
case ProcessPaused:
m_bAbortEventPollingLoop = true;
resume();
break;
}
QThread::wait(5000);
if (QThread::isRunning()) {
qWarning("WinDbgThread still running... terminating!");
QThread::terminate();
}
}
void WinDbgThread::attachToProcess(DWORD processId)
{
m_bOwnsProcess = false;
m_processFileName = QString();
m_pi.dwProcessId = processId;
QThread::start();
}
void WinDbgThread::run()
{
qDebug() << "WinDbgThread started";
// start process or attach process
if (m_bOwnsProcess) {
// create new process
internalStartProcess();
} else {
// attach to process
qWarning("attach to process not yet implemented");
return;
}
m_hThisThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, GetCurrentThreadId());
if (!m_hThisThread) {
qWarning("WinDbgThread: can't open thread handle");
return;
}
DEBUG_EVENT debugEvent;
m_bAbortEventPollingLoop = false;
while (WaitForDebugEvent(&debugEvent, INFINITE)) {
setState(ProcessPaused);
emit debugEventOccured(&debugEvent);
suspend();
if (m_bAbortEventPollingLoop)
break;
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
setState(ProcessRunning);
}
setState(Idle);
if (m_bOwnsProcess) {
TerminateProcess(m_pi.hProcess, 0);
}
CloseHandle(m_pi.hProcess);
CloseHandle(m_pi.hThread);
CloseHandle(m_hThisThread);
qDebug() << "WinDbgThread finished";
}
void WinDbgThread::continueProcess()
{
if (m_state == ProcessPaused)
resume();
}
void WinDbgThread::pauseProcess()
{
if (m_state == ProcessRunning)
DebugBreakProcess(m_pi.hProcess);
}
void WinDbgThread::internalStartProcess()
{
BOOL bSuccess;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = TRUE;
ZeroMemory(&m_pi, sizeof(m_pi));
DWORD dwCreationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
bSuccess = CreateProcess(m_processFileName.utf16(), NULL, NULL, NULL, FALSE,
dwCreationFlags,
NULL, NULL, &si, &m_pi
);
if (bSuccess)
setState(ProcessRunning);
else
setState(Idle);
}
void WinDbgThread::setState(State s)
{
m_state = s;
}
void WinDbgThread::suspend()
{
SuspendThread(m_hThisThread);
}
void WinDbgThread::resume()
{
ResumeThread(m_hThisThread);
}