From 585caded11430952c152a15c4b369e7ae7d9eb17 Mon Sep 17 00:00:00 2001 From: eddyStreamlabs Date: Mon, 3 Dec 2018 16:32:25 -0800 Subject: [PATCH 1/4] Fix catch crashes on exit --- crash-handler-process/main.cpp | 3 ++- crash-handler-process/process.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crash-handler-process/main.cpp b/crash-handler-process/main.cpp index 45c52ac..da5ed3e 100644 --- a/crash-handler-process/main.cpp +++ b/crash-handler-process/main.cpp @@ -201,8 +201,9 @@ void checkProcesses(std::mutex &m) { while (alive && index < processes.size()) { monitoring = true; - std::unique_lock ulock(processes.at(index)->mutex); + processes.at(index)->mutex.lock(); alive = processes.at(index)->getAlive(); + processes.at(index)->mutex.unlock(); index++; } if (!alive) { diff --git a/crash-handler-process/process.cpp b/crash-handler-process/process.cpp index 887b08b..c96bcac 100644 --- a/crash-handler-process/process.cpp +++ b/crash-handler-process/process.cpp @@ -7,8 +7,10 @@ void check(void* p) { proc->setAlive(true); if (!WaitForSingleObject(proc->getHandle(), INFINITE)) { + proc->mutex.lock(); proc->setAlive(false); proc->stopWorker(); + proc->mutex.unlock(); } } From 9a10be6e23ab6c62d24152091f71c339909fd23d Mon Sep 17 00:00:00 2001 From: eddyStreamlabs Date: Tue, 4 Dec 2018 17:15:43 -0800 Subject: [PATCH 2/4] Prevent possible race condition --- crash-handler-process/main.cpp | 26 ++++---- crash-handler-process/namedsocket-win.cpp | 80 +++++++++++++---------- crash-handler-process/namedsocket-win.hpp | 2 +- crash-handler-process/namedsocket.hpp | 2 +- 4 files changed, 61 insertions(+), 49 deletions(-) diff --git a/crash-handler-process/main.cpp b/crash-handler-process/main.cpp index da5ed3e..4daae8d 100644 --- a/crash-handler-process/main.cpp +++ b/crash-handler-process/main.cpp @@ -15,11 +15,11 @@ VOID DisconnectAndReconnect(DWORD); BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED); std::vector processes; -bool exitApp = false; +bool* exitApp = nullptr; bool doRestartApp = false; bool monitoring = false; bool closeAll = false; -std::mutex mu; +std::mutex* mu = new std::mutex(); static thread_local std::wstring_convert> converter; std::string from_utf16_wide_to_utf8(const wchar_t* from, size_t length = -1) @@ -187,15 +187,15 @@ void terminalCriticalProcesses(void) { } } -void checkProcesses(std::mutex &m) { +void checkProcesses(std::mutex* m) { - while (!exitApp) { - m.lock(); + while (!(*exitApp)) { + m->lock(); bool alive = true; size_t index = 0; if (monitoring && processes.size() == 0) { - exitApp = true; + *exitApp = true; break; } @@ -244,14 +244,14 @@ void checkProcesses(std::mutex &m) { else { closeAll = true; } - exitApp = true; + *exitApp = true; } else { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } - m.unlock(); + m->unlock(); } - exitApp = true; + *exitApp = true; } void close(bool doCloseALl) { @@ -316,16 +316,18 @@ int main(int argc, char** argv) uint64_t currentPID = GetCurrentProcessId(); write_pid_file(pid_path, currentPID); - std::thread processManager(checkProcesses, std::ref(mu)); + exitApp = new bool(false); + + std::thread processManager(checkProcesses, mu); std::unique_ptr sock = NamedSocket::create(); - while (!exitApp && !sock->read(&processes, std::ref(mu))) + while (!(*exitApp) && !sock->read(&processes, mu, exitApp)) { } - exitApp = true; + *exitApp = true; if (processManager.joinable()) processManager.join(); close(closeAll); diff --git a/crash-handler-process/namedsocket-win.cpp b/crash-handler-process/namedsocket-win.cpp index a0f353c..3043550 100644 --- a/crash-handler-process/namedsocket-win.cpp +++ b/crash-handler-process/namedsocket-win.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #define CONNECTING_STATE 0 #define READING_STATE 1 @@ -25,6 +26,8 @@ typedef struct PIPEINST Pipe[INSTANCES]; HANDLE hEvents[INSTANCES]; +std::vector requests; + BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo) { BOOL fConnected, fPendingIO = FALSE; @@ -135,10 +138,46 @@ NamedSocket_win::~NamedSocket_win() { DisconnectNamedPipe(m_handle); } -bool NamedSocket_win::read(std::vector* processes, std::mutex &mu) { +void processRequest(std::vector p_buffer, std::vector* processes, std::mutex* mu, bool* exitApp) { + Message msg(p_buffer); + mu->lock(); + switch (msg.readBool()) { + case REGISTER: { + bool isCritical = msg.readBool(); + uint32_t pid = msg.readUInt32(); + processes->push_back(new Process(pid, isCritical)); + break; + } + case UNREGISTER: { + uint32_t pid = msg.readUInt32(); + auto it = std::find_if(processes->begin(), processes->end(), [&pid](Process* p) { + return p->getPID() == pid; + }); + + if (it != processes->end()) { + Process* p = (Process*)(*it); + p->stopWorker(); + if (p->getWorker()->joinable()) + p->getWorker()->join(); + + processes->erase(it); + + if (p->getCritical()) + *exitApp = true; + } + break; + } + case EXIT: + *exitApp = true; + default: + break; + } + mu->unlock(); +} + +bool NamedSocket_win::read(std::vector* processes, std::mutex* mu, bool* exit) { DWORD i, dwWait, cbRet, dwErr; BOOL fSuccess; - bool exitApp = false; dwWait = WaitForMultipleObjects( INSTANCES, @@ -208,38 +247,9 @@ bool NamedSocket_win::read(std::vector* processes, std::mutex &mu) { // The read operation completed successfully. if (Pipe[i].cbRead > 0) { Pipe[i].fPendingIO = FALSE; - Message msg(Pipe[i].chRequest); - - switch (msg.readBool()) { - case REGISTER: { - bool isCritical = msg.readBool(); - uint32_t pid = msg.readUInt32(); - processes->push_back(new Process(pid, isCritical)); - break; - } - case UNREGISTER: { - uint32_t pid = msg.readUInt32(); - auto it = std::find_if(processes->begin(), processes->end(), [&pid](Process* p) { - return p->getPID() == pid; - }); - - mu.lock(); - if (it != processes->end()) { - Process* p = (Process*)(*it); - p->stopWorker(); - if (p->getWorker()->joinable()) - p->getWorker()->join(); - - processes->erase(it); - } - mu.unlock(); - break; - } - case EXIT: - exitApp = true; - default: - break; - } + + // Start thread here + requests.push_back(new std::thread(processRequest, Pipe[i].chRequest, processes, mu, exit)); } dwErr = GetLastError(); if (!fSuccess && (dwErr == ERROR_IO_PENDING)) @@ -251,7 +261,7 @@ bool NamedSocket_win::read(std::vector* processes, std::mutex &mu) { break; } } - return exitApp; + return false; } bool NamedSocket_win::flush() { diff --git a/crash-handler-process/namedsocket-win.hpp b/crash-handler-process/namedsocket-win.hpp index 6d68a40..474db94 100644 --- a/crash-handler-process/namedsocket-win.hpp +++ b/crash-handler-process/namedsocket-win.hpp @@ -11,7 +11,7 @@ class NamedSocket_win : public NamedSocket { public: virtual bool connect() override; - virtual bool read(std::vector*, std::mutex &mu) override; + virtual bool read(std::vector*, std::mutex* mu, bool* exit) override; virtual void disconnect() override; virtual bool flush() override; diff --git a/crash-handler-process/namedsocket.hpp b/crash-handler-process/namedsocket.hpp index ea00a6d..760cc9f 100644 --- a/crash-handler-process/namedsocket.hpp +++ b/crash-handler-process/namedsocket.hpp @@ -10,7 +10,7 @@ class NamedSocket { static std::unique_ptr create(); virtual bool connect() = 0; virtual void disconnect() = 0; - virtual bool read(std::vector*, std::mutex &mu) = 0; + virtual bool read(std::vector*, std::mutex* mu, bool* exit) = 0; virtual bool flush() = 0; virtual HANDLE getHandle() = 0; }; \ No newline at end of file From 5596e7f220b8c85452e48166c95a4c473ade1c15 Mon Sep 17 00:00:00 2001 From: eddyStreamlabs Date: Tue, 4 Dec 2018 18:28:29 -0800 Subject: [PATCH 3/4] Send acknowledge on unregister --- crash-handler-process/main.cpp | 4 ++- crash-handler-process/namedsocket-win.cpp | 33 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/crash-handler-process/main.cpp b/crash-handler-process/main.cpp index 4daae8d..b3870fe 100644 --- a/crash-handler-process/main.cpp +++ b/crash-handler-process/main.cpp @@ -206,6 +206,9 @@ void checkProcesses(std::mutex* m) { processes.at(index)->mutex.unlock(); index++; } + + m->unlock(); + if (!alive) { index--; if (!processes.at(index)->getCritical()) { @@ -249,7 +252,6 @@ void checkProcesses(std::mutex* m) { else { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } - m->unlock(); } *exitApp = true; } diff --git a/crash-handler-process/namedsocket-win.cpp b/crash-handler-process/namedsocket-win.cpp index 3043550..be40938 100644 --- a/crash-handler-process/namedsocket-win.cpp +++ b/crash-handler-process/namedsocket-win.cpp @@ -138,6 +138,36 @@ NamedSocket_win::~NamedSocket_win() { DisconnectNamedPipe(m_handle); } +void acknowledgeUnregister(void) { + std::cout << "Send ack" << std::endl; + std::string buffer = "exit"; + HANDLE hPipe = CreateFile( + TEXT("\\\\.\\pipe\\exit-slobs-crash-handler"), + GENERIC_READ | + GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); + + if (hPipe == INVALID_HANDLE_VALUE) + return; + + if (GetLastError() == ERROR_PIPE_BUSY) + return; + + DWORD bytesWritten; + + WriteFile( + hPipe, + buffer.data(), + buffer.size(), &bytesWritten, + NULL); + + CloseHandle(hPipe); +} + void processRequest(std::vector p_buffer, std::vector* processes, std::mutex* mu, bool* exitApp) { Message msg(p_buffer); mu->lock(); @@ -157,14 +187,13 @@ void processRequest(std::vector p_buffer, std::vector* processe if (it != processes->end()) { Process* p = (Process*)(*it); p->stopWorker(); - if (p->getWorker()->joinable()) - p->getWorker()->join(); processes->erase(it); if (p->getCritical()) *exitApp = true; } + acknowledgeUnregister(); break; } case EXIT: From 8c10cac9f2b960917e0449679ffb2a0d1be7e02b Mon Sep 17 00:00:00 2001 From: eddyStreamlabs Date: Wed, 5 Dec 2018 11:28:25 -0800 Subject: [PATCH 4/4] Remove log --- crash-handler-process/namedsocket-win.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/crash-handler-process/namedsocket-win.cpp b/crash-handler-process/namedsocket-win.cpp index be40938..269cfd9 100644 --- a/crash-handler-process/namedsocket-win.cpp +++ b/crash-handler-process/namedsocket-win.cpp @@ -139,7 +139,6 @@ NamedSocket_win::~NamedSocket_win() { } void acknowledgeUnregister(void) { - std::cout << "Send ack" << std::endl; std::string buffer = "exit"; HANDLE hPipe = CreateFile( TEXT("\\\\.\\pipe\\exit-slobs-crash-handler"),