1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-11-08 21:16:40 +00:00

Merge branch 'no-crash-dump-in-temp-0.48' into 'openmw-48'

Don't put crash dumps in Temp on Windows

See merge request OpenMW/openmw!3199
This commit is contained in:
psi29a 2023-07-08 12:36:59 +00:00
commit 99c07153e7
6 changed files with 81 additions and 19 deletions

View file

@ -26,7 +26,7 @@ namespace Crash
CrashCatcher* CrashCatcher::sInstance = nullptr; CrashCatcher* CrashCatcher::sInstance = nullptr;
CrashCatcher::CrashCatcher(int argc, char **argv, const std::string& crashLogPath) CrashCatcher::CrashCatcher(int argc, char** argv, const std::string& crashDumpPath, const std::string& freezeDumpPath)
{ {
assert(sInstance == nullptr); // don't allow two instances assert(sInstance == nullptr); // don't allow two instances
@ -48,7 +48,7 @@ namespace Crash
if (!shmHandle) if (!shmHandle)
{ {
setupIpc(); setupIpc();
startMonitorProcess(crashLogPath); startMonitorProcess(crashDumpPath, freezeDumpPath);
installHandler(); installHandler();
} }
else else
@ -75,6 +75,25 @@ namespace Crash
CloseHandle(mShmHandle); CloseHandle(mShmHandle);
} }
void CrashCatcher::updateDumpPaths(const std::string& crashDumpPath, const std::string& freezeDumpPath)
{
shmLock();
memset(mShm->mStartup.mCrashDumpFilePath, 0, sizeof(mShm->mStartup.mCrashDumpFilePath));
size_t length = crashDumpPath.length();
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
strncpy(mShm->mStartup.mCrashDumpFilePath, crashDumpPath.c_str(), length);
mShm->mStartup.mCrashDumpFilePath[length] = '\0';
memset(mShm->mStartup.mFreezeDumpFilePath, 0, sizeof(mShm->mStartup.mFreezeDumpFilePath));
length = freezeDumpPath.length();
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
strncpy(mShm->mStartup.mFreezeDumpFilePath, freezeDumpPath.c_str(), length);
mShm->mStartup.mFreezeDumpFilePath[length] = '\0';
shmUnlock();
}
void CrashCatcher::setupIpc() void CrashCatcher::setupIpc()
{ {
SECURITY_ATTRIBUTES attributes; SECURITY_ATTRIBUTES attributes;
@ -124,7 +143,7 @@ namespace Crash
SetUnhandledExceptionFilter(vectoredExceptionHandler); SetUnhandledExceptionFilter(vectoredExceptionHandler);
} }
void CrashCatcher::startMonitorProcess(const std::string& crashLogPath) void CrashCatcher::startMonitorProcess(const std::string& crashDumpPath, const std::string& freezeDumpPath)
{ {
std::wstring executablePath; std::wstring executablePath;
DWORD copied = 0; DWORD copied = 0;
@ -134,11 +153,17 @@ namespace Crash
} while (copied >= executablePath.size()); } while (copied >= executablePath.size());
executablePath.resize(copied); executablePath.resize(copied);
memset(mShm->mStartup.mLogFilePath, 0, sizeof(mShm->mStartup.mLogFilePath)); memset(mShm->mStartup.mCrashDumpFilePath, 0, sizeof(mShm->mStartup.mCrashDumpFilePath));
size_t length = crashLogPath.length(); size_t length = crashDumpPath.length();
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1; if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
strncpy(mShm->mStartup.mLogFilePath, crashLogPath.c_str(), length); strncpy(mShm->mStartup.mCrashDumpFilePath, crashDumpPath.c_str(), length);
mShm->mStartup.mLogFilePath[length] = '\0'; mShm->mStartup.mCrashDumpFilePath[length] = '\0';
memset(mShm->mStartup.mFreezeDumpFilePath, 0, sizeof(mShm->mStartup.mFreezeDumpFilePath));
length = freezeDumpPath.length();
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
strncpy(mShm->mStartup.mFreezeDumpFilePath, freezeDumpPath.c_str(), length);
mShm->mStartup.mFreezeDumpFilePath[length] = '\0';
// note that we don't need to lock the SHM here, the other process has not started yet // note that we don't need to lock the SHM here, the other process has not started yet
mShm->mEvent = CrashSHM::Event::Startup; mShm->mEvent = CrashSHM::Event::Startup;
@ -197,7 +222,7 @@ namespace Crash
// must remain until monitor has finished // must remain until monitor has finished
waitMonitor(); waitMonitor();
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(mShm->mStartup.mLogFilePath) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !"; std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(mShm->mStartup.mCrashDumpFilePath) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr); SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
} }

View file

@ -27,10 +27,16 @@ namespace Crash
class CrashCatcher final class CrashCatcher final
{ {
public: public:
static CrashCatcher* instance()
{
return sInstance;
}
CrashCatcher(int argc, char **argv, const std::string& crashLogPath); CrashCatcher(int argc, char** argv, const std::string& crashDumpPath, const std::string& freezeDumpPath);
~CrashCatcher(); ~CrashCatcher();
void updateDumpPaths(const std::string& crashDumpPath, const std::string& freezeDumpPath);
private: private:
static CrashCatcher* sInstance; static CrashCatcher* sInstance;
@ -56,7 +62,7 @@ namespace Crash
void shmUnlock(); void shmUnlock();
void startMonitorProcess(const std::string& crashLogPath); void startMonitorProcess(const std::string& crashDumpPath, const std::string& freezeDumpPath);
void waitMonitor(); void waitMonitor();

View file

@ -186,7 +186,7 @@ namespace Crash
case CrashSHM::Event::None: case CrashSHM::Event::None:
break; break;
case CrashSHM::Event::Crashed: case CrashSHM::Event::Crashed:
handleCrash(); handleCrash(false);
running = false; running = false;
break; break;
case CrashSHM::Event::Shutdown: case CrashSHM::Event::Shutdown:
@ -205,9 +205,9 @@ namespace Crash
if (mFreezeAbort) if (mFreezeAbort)
{ {
handleCrash(); handleCrash(true);
TerminateProcess(mAppProcessHandle, 0xDEAD); TerminateProcess(mAppProcessHandle, 0xDEAD);
std::string message = "OpenMW appears to have frozen.\nCrash log saved to '" + std::string(mShm->mStartup.mLogFilePath) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !"; std::string message = "OpenMW appears to have frozen.\nCrash log saved to '" + std::string(mShm->mStartup.mFreezeDumpFilePath) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr); SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
} }
@ -231,7 +231,7 @@ namespace Crash
return utf16; return utf16;
} }
void CrashMonitor::handleCrash() void CrashMonitor::handleCrash(bool isFreeze)
{ {
DWORD processId = GetProcessId(mAppProcessHandle); DWORD processId = GetProcessId(mAppProcessHandle);
@ -250,7 +250,7 @@ namespace Crash
if (miniDumpWriteDump == NULL) if (miniDumpWriteDump == NULL)
return; return;
std::wstring utf16Path = utf8ToUtf16(mShm->mStartup.mLogFilePath); std::wstring utf16Path = utf8ToUtf16(isFreeze ? mShm->mStartup.mFreezeDumpFilePath : mShm->mStartup.mCrashDumpFilePath);
if (utf16Path.empty()) if (utf16Path.empty())
return; return;

View file

@ -53,7 +53,7 @@ private:
void shmUnlock(); void shmUnlock();
void handleCrash(); void handleCrash(bool isFreeze);
void showFreezeMessageBox(); void showFreezeMessageBox();

View file

@ -28,7 +28,8 @@ namespace Crash
HANDLE mSignalApp; HANDLE mSignalApp;
HANDLE mSignalMonitor; HANDLE mSignalMonitor;
HANDLE mShmMutex; HANDLE mShmMutex;
char mLogFilePath[MAX_LONG_PATH]; char mCrashDumpFilePath[MAX_LONG_PATH];
char mFreezeDumpFilePath[MAX_LONG_PATH];
} mStartup; } mStartup;
struct Crashed struct Crashed

View file

@ -9,6 +9,18 @@
#ifdef _WIN32 #ifdef _WIN32
#include <components/crashcatcher/windows_crashcatcher.hpp> #include <components/crashcatcher/windows_crashcatcher.hpp>
#include <components/windows.hpp> #include <components/windows.hpp>
#include <Knownfolders.h>
#pragma push_macro("FAR")
#pragma push_macro("NEAR")
#undef FAR
#define FAR
#undef NEAR
#define NEAR
#include <Shlobj.h>
#pragma pop_macro("NEAR")
#pragma pop_macro("FAR")
#endif #endif
#include <SDL_messagebox.h> #include <SDL_messagebox.h>
@ -284,6 +296,16 @@ void setupLogging(const std::string& logDir, std::string_view appName)
std::cout.rdbuf(&coutsb); std::cout.rdbuf(&coutsb);
std::cerr.rdbuf(&cerrsb); std::cerr.rdbuf(&cerrsb);
#endif #endif
#ifdef _WIN32
if (Crash::CrashCatcher::instance())
{
const std::string crashDumpName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp";
const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp";
boost::filesystem::path dumpDirectory(logDir);
Crash::CrashCatcher::instance()->updateDumpPaths((dumpDirectory / crashDumpName).make_preferred().string(), (dumpDirectory / freezeDumpName).make_preferred().string());
}
#endif
} }
int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[], int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[],
@ -304,8 +326,16 @@ int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, c
if (const auto env = std::getenv("OPENMW_DISABLE_CRASH_CATCHER"); env == nullptr || std::atol(env) == 0) if (const auto env = std::getenv("OPENMW_DISABLE_CRASH_CATCHER"); env == nullptr || std::atol(env) == 0)
{ {
#if defined(_WIN32) #if defined(_WIN32)
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp"; const std::string crashDumpName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp";
Crash::CrashCatcher crashy(argc, argv, (boost::filesystem::temp_directory_path() / crashLogName).make_preferred().string()); const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp";
boost::filesystem::path dumpDirectory = boost::filesystem::temp_directory_path();
PWSTR userProfile = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &userProfile)))
{
dumpDirectory = userProfile;
}
CoTaskMemFree(userProfile);
Crash::CrashCatcher crashy(argc, argv, (dumpDirectory / crashDumpName).make_preferred().string(), (dumpDirectory / freezeDumpName).make_preferred().string());
#else #else
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log"; const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log";
// install the crash handler as soon as possible. note that the log path // install the crash handler as soon as possible. note that the log path