diff --git a/include/logvisor/logvisor.hpp b/include/logvisor/logvisor.hpp index 98d6f47..8ecdd2b 100644 --- a/include/logvisor/logvisor.hpp +++ b/include/logvisor/logvisor.hpp @@ -53,6 +53,13 @@ struct ILogger const wchar_t* format, va_list ap)=0; }; +/** + * @brief Terminate all child processes + * + * Implicitly called on abort condition. + */ +void KillProcessTree(); + /** * @brief Assign calling thread a descriptive name * @param name Descriptive thread name diff --git a/lib/logvisor.cpp b/lib/logvisor.cpp index acfa4a2..73e4fe2 100644 --- a/lib/logvisor.cpp +++ b/lib/logvisor.cpp @@ -7,6 +7,8 @@ #endif #include #include +#include +#include #else #include #include @@ -79,7 +81,6 @@ void RegisterThreadName(const char* name) } #if _WIN32 -#include #pragma comment(lib, "Dbghelp.lib") #if defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP @@ -88,6 +89,38 @@ void RegisterThreadName(const char* name) #define WINDOWS_STORE 0 #endif +void KillProcessTree() +{ + DWORD myprocID = GetCurrentProcessId(); + PROCESSENTRY32 pe = {}; + pe.dwSize = sizeof(PROCESSENTRY32); + + HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (::Process32First(hSnap, &pe)) + { + BOOL bContinue = TRUE; + + // kill child processes + while (bContinue) + { + // only kill child processes + if (pe.th32ParentProcessID == myprocID) + { + HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID); + + if (hChildProc) + { + ::TerminateProcess(hChildProc, 1); + ::CloseHandle(hChildProc); + } + } + + bContinue = ::Process32Next(hSnap, &pe); + } + } +} + void logvisorAbort() { #if !WINDOWS_STORE @@ -130,6 +163,9 @@ void logvisorAbort() free(symbol); #endif + + KillProcessTree(); + // If you caught one of the above signals, it is likely you just // want to quit your program right now. signal(SIGABRT, SIG_DFL); @@ -137,6 +173,8 @@ void logvisorAbort() } #else +void KillProcessTree() {} + #include void logvisorAbort() { @@ -204,6 +242,7 @@ void logvisorAbort() fflush(stderr); fflush(stdout); + KillProcessTree(); signal(SIGABRT, SIG_DFL); abort(); } @@ -420,6 +459,7 @@ struct ConsoleLogger : public ILogger _reportHead(modName, nullptr, severity); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); + fflush(stderr); } void report(const char* modName, Level severity, @@ -428,6 +468,7 @@ struct ConsoleLogger : public ILogger _reportHead(modName, nullptr, severity); vfwprintf(stderr, format, ap); fprintf(stderr, "\n"); + fflush(stderr); } void reportSource(const char* modName, Level severity, @@ -439,6 +480,7 @@ struct ConsoleLogger : public ILogger _reportHead(modName, sourceInfo, severity); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); + fflush(stderr); } void reportSource(const char* modName, Level severity, @@ -450,6 +492,7 @@ struct ConsoleLogger : public ILogger _reportHead(modName, sourceInfo, severity); vfwprintf(stderr, format, ap); fprintf(stderr, "\n"); + fflush(stderr); } };