Commit 00298ab2 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

WinGuiProcess: Fix hang if binary cannot be found.



..occurring in conjunction with custom run configuration
and S60 emulator. Ensure all handles are closed even
if start attempt failed.
Reviewed-by: default avatarcon <qtc-committer@nokia.com>
parent 2ea07637
......@@ -101,72 +101,81 @@ void WinGuiProcess::run()
ZeroMemory(m_pid, sizeof(PROCESS_INFORMATION));
m_exitCode = 0;
bool started = false;
HANDLE bufferReadyEvent = NULL;
HANDLE dataReadyEvent = NULL;
HANDLE sharedFile = NULL;
LPVOID sharedMem = NULL;
bool dbgInterface = setupDebugInterface(bufferReadyEvent, dataReadyEvent, sharedFile, sharedMem);
QString cmdLine = createWinCommandline(m_program, m_args);
bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT,
environment().isEmpty() ? 0
: createWinEnvironment(fixWinEnvironment(environment())).data(),
workingDirectory().isEmpty() ? 0
: (WCHAR*)QDir::convertSeparators(workingDirectory()).utf16(),
&si, m_pid);
if (!success) {
emit processError(tr("The process could not be started!"));
delete m_pid;
m_pid = 0;
return;
}
LPVOID sharedMem = 0;
if (!dbgInterface) {
emit receivedDebugOutput(tr("Cannot retrieve debugging output!"));
WaitForSingleObject(m_pid->hProcess, INFINITE);
} else {
LPSTR message;
LPDWORD processId;
HANDLE toWaitFor[2];
message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD);
processId = reinterpret_cast<LPDWORD>(sharedMem);
SetEvent(bufferReadyEvent);
toWaitFor[0] = dataReadyEvent;
toWaitFor[1] = m_pid->hProcess;
for (bool stop = false; !stop;) {
DWORD ret = WaitForMultipleObjects(2, toWaitFor, FALSE, INFINITE);
switch (ret) {
case WAIT_OBJECT_0 + 0:
if (*processId == m_pid->dwProcessId)
emit receivedDebugOutput(QString::fromLocal8Bit(message));
SetEvent(bufferReadyEvent);
break;
case WAIT_OBJECT_0 + 1:
stop = true;
break;
}
do {
const bool dbgInterface = setupDebugInterface(bufferReadyEvent, dataReadyEvent, sharedFile, sharedMem);
const QString cmdLine = createWinCommandline(m_program, m_args);
started = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT,
environment().isEmpty() ? 0
: createWinEnvironment(fixWinEnvironment(environment())).data(),
workingDirectory().isEmpty() ? 0
: (WCHAR*)QDir::convertSeparators(workingDirectory()).utf16(),
&si, m_pid);
if (!started) {
emit processError(tr("The process could not be started!"));
break;
}
}
GetExitCodeProcess(m_pid->hProcess, &m_exitCode);
emit processFinished(static_cast<int>(m_exitCode));
if (!dbgInterface) {
emit receivedDebugOutput(tr("Cannot retrieve debugging output!"));
WaitForSingleObject(m_pid->hProcess, INFINITE);
} else {
LPSTR message;
LPDWORD processId;
HANDLE toWaitFor[2];
message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD);
processId = reinterpret_cast<LPDWORD>(sharedMem);
SetEvent(bufferReadyEvent);
toWaitFor[0] = dataReadyEvent;
toWaitFor[1] = m_pid->hProcess;
for (bool stop = false; !stop;) {
DWORD ret = WaitForMultipleObjects(2, toWaitFor, FALSE, INFINITE);
switch (ret) {
case WAIT_OBJECT_0 + 0:
if (*processId == m_pid->dwProcessId)
emit receivedDebugOutput(QString::fromLocal8Bit(message));
SetEvent(bufferReadyEvent);
break;
case WAIT_OBJECT_0 + 1:
stop = true;
break;
}
}
}
} while (false);
UnmapViewOfFile(sharedMem);
CloseHandle(sharedFile);
CloseHandle(bufferReadyEvent);
CloseHandle(dataReadyEvent);
CloseHandle(m_pid->hProcess);
CloseHandle(m_pid->hThread);
if (started) {
GetExitCodeProcess(m_pid->hProcess, &m_exitCode);
emit processFinished(static_cast<int>(m_exitCode));
}
if (sharedMem)
UnmapViewOfFile(sharedMem);
if (sharedFile != NULL)
CloseHandle(sharedFile);
if (bufferReadyEvent != NULL)
CloseHandle(bufferReadyEvent);
if (dataReadyEvent != NULL)
CloseHandle(dataReadyEvent);
if (m_pid->hProcess != NULL)
CloseHandle(m_pid->hProcess);
if (m_pid->hThread != NULL)
CloseHandle(m_pid->hThread);
delete m_pid;
m_pid = 0;
}
......
......@@ -42,6 +42,9 @@ using namespace Utils;
namespace ProjectExplorer {
namespace Internal {
/* Captures the debug output of a Windows GUI application (which
* would otherwise not be visible) using the debug interface and
* emits via a signal. */
class WinGuiProcess : public QThread, public AbstractProcess
{
Q_OBJECT
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment