Wait for waitingThread to exit before destroying the subprocess memory.

WaitingThread read some shared memory with the SubProcess
(`mutex`, `m_running`).
When we destroy the SubProcess, we must be sure that WaitingThread has
correctly finished else we may have invalid read/write on freed memory.
This commit is contained in:
Matthieu Gautier 2020-08-25 16:10:21 +02:00
parent 4e98a76c19
commit 39611cbd60
3 changed files with 11 additions and 7 deletions

View File

@ -26,6 +26,7 @@ UnixImpl::~UnixImpl()
#else #else
pthread_cancel(m_waitingThread); pthread_cancel(m_waitingThread);
#endif #endif
pthread_join(m_waitingThread, nullptr);
} }
#ifdef __ANDROID__ #ifdef __ANDROID__

View File

@ -11,7 +11,8 @@
WinImpl::WinImpl(): WinImpl::WinImpl():
m_pid(0), m_pid(0),
m_running(false), m_running(false),
m_handle(INVALID_HANDLE_VALUE) m_subprocessHandle(INVALID_HANDLE_VALUE),
m_waitingThreadHandle(INVALID_HANDLE_VALUE)
{ {
InitializeCriticalSection(&m_criticalSection); InitializeCriticalSection(&m_criticalSection);
} }
@ -19,14 +20,15 @@ WinImpl::WinImpl():
WinImpl::~WinImpl() WinImpl::~WinImpl()
{ {
kill(); kill();
CloseHandle(m_handle); WaitForSingleObject(m_waitingThreadHandle, INFINITE);
CloseHandle(m_subprocessHandle);
DeleteCriticalSection(&m_criticalSection); DeleteCriticalSection(&m_criticalSection);
} }
DWORD WINAPI WinImpl::waitForPID(void* _self) DWORD WINAPI WinImpl::waitForPID(void* _self)
{ {
WinImpl* self = static_cast<WinImpl*>(_self); WinImpl* self = static_cast<WinImpl*>(_self);
WaitForSingleObject(self->m_handle, INFINITE); WaitForSingleObject(self->m_subprocessHandle, INFINITE);
EnterCriticalSection(&self->m_criticalSection); EnterCriticalSection(&self->m_criticalSection);
self->m_running = false; self->m_running = false;
@ -79,16 +81,16 @@ void WinImpl::run(commandLine_t& commandLine)
&procInfo)) &procInfo))
{ {
m_pid = procInfo.dwProcessId; m_pid = procInfo.dwProcessId;
m_handle = procInfo.hProcess; m_subprocessHandle = procInfo.hProcess;
CloseHandle(procInfo.hThread); CloseHandle(procInfo.hThread);
m_running = true; m_running = true;
CreateThread(NULL, 0, &waitForPID, this, 0, NULL ); m_waitingThreadHandle = CreateThread(NULL, 0, &waitForPID, this, 0, NULL);
} }
} }
bool WinImpl::kill() bool WinImpl::kill()
{ {
return TerminateProcess(m_handle, 0); return TerminateProcess(m_subprocessHandle, 0);
} }
bool WinImpl::isRunning() bool WinImpl::isRunning()

View File

@ -11,7 +11,8 @@ class WinImpl : public SubprocessImpl
private: private:
int m_pid; int m_pid;
bool m_running; bool m_running;
HANDLE m_handle; HANDLE m_subprocessHandle;
HANDLE m_waitingThreadHandle;
CRITICAL_SECTION m_criticalSection; CRITICAL_SECTION m_criticalSection;
public: public: