mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-23 06:41:08 +00:00
Merge branch 'no-crash-dump-in-temp' into 'master'
Don't put crash dumps in Temp on Windows Closes #7455 See merge request OpenMW/openmw!3200
This commit is contained in:
commit
da592356f1
@ -27,7 +27,8 @@ namespace Crash
|
|||||||
|
|
||||||
CrashCatcher* CrashCatcher::sInstance = nullptr;
|
CrashCatcher* CrashCatcher::sInstance = nullptr;
|
||||||
|
|
||||||
CrashCatcher::CrashCatcher(int argc, char** argv, const std::filesystem::path& crashLogPath)
|
CrashCatcher::CrashCatcher(
|
||||||
|
int argc, char** argv, const std::filesystem::path& crashDumpPath, const std::filesystem::path& freezeDumpPath)
|
||||||
{
|
{
|
||||||
assert(sInstance == nullptr); // don't allow two instances
|
assert(sInstance == nullptr); // don't allow two instances
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ namespace Crash
|
|||||||
if (!shmHandle)
|
if (!shmHandle)
|
||||||
{
|
{
|
||||||
setupIpc();
|
setupIpc();
|
||||||
startMonitorProcess(crashLogPath);
|
startMonitorProcess(crashDumpPath, freezeDumpPath);
|
||||||
installHandler();
|
installHandler();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -76,6 +77,32 @@ namespace Crash
|
|||||||
CloseHandle(mShmHandle);
|
CloseHandle(mShmHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CrashCatcher::updateDumpPaths(
|
||||||
|
const std::filesystem::path& crashDumpPath, const std::filesystem::path& freezeDumpPath)
|
||||||
|
{
|
||||||
|
shmLock();
|
||||||
|
|
||||||
|
memset(mShm->mStartup.mCrashDumpFilePath, 0, sizeof(mShm->mStartup.mCrashDumpFilePath));
|
||||||
|
const auto str = crashDumpPath.u8string();
|
||||||
|
size_t length = str.length();
|
||||||
|
if (length >= MAX_LONG_PATH)
|
||||||
|
length = MAX_LONG_PATH - 1;
|
||||||
|
strncpy_s(mShm->mStartup.mCrashDumpFilePath, sizeof mShm->mStartup.mCrashDumpFilePath,
|
||||||
|
Misc::StringUtils::u8StringToString(str).c_str(), length);
|
||||||
|
mShm->mStartup.mCrashDumpFilePath[length] = '\0';
|
||||||
|
|
||||||
|
memset(mShm->mStartup.mFreezeDumpFilePath, 0, sizeof(mShm->mStartup.mFreezeDumpFilePath));
|
||||||
|
const auto strFreeze = freezeDumpPath.u8string();
|
||||||
|
length = strFreeze.length();
|
||||||
|
if (length >= MAX_LONG_PATH)
|
||||||
|
length = MAX_LONG_PATH - 1;
|
||||||
|
strncpy_s(mShm->mStartup.mFreezeDumpFilePath, sizeof mShm->mStartup.mFreezeDumpFilePath,
|
||||||
|
Misc::StringUtils::u8StringToString(strFreeze).c_str(), length);
|
||||||
|
mShm->mStartup.mFreezeDumpFilePath[length] = '\0';
|
||||||
|
|
||||||
|
shmUnlock();
|
||||||
|
}
|
||||||
|
|
||||||
void CrashCatcher::setupIpc()
|
void CrashCatcher::setupIpc()
|
||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES attributes;
|
SECURITY_ATTRIBUTES attributes;
|
||||||
@ -126,7 +153,8 @@ namespace Crash
|
|||||||
SetUnhandledExceptionFilter(vectoredExceptionHandler);
|
SetUnhandledExceptionFilter(vectoredExceptionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrashCatcher::startMonitorProcess(const std::filesystem::path& crashLogPath)
|
void CrashCatcher::startMonitorProcess(
|
||||||
|
const std::filesystem::path& crashDumpPath, const std::filesystem::path& freezeDumpPath)
|
||||||
{
|
{
|
||||||
std::wstring executablePath;
|
std::wstring executablePath;
|
||||||
DWORD copied = 0;
|
DWORD copied = 0;
|
||||||
@ -137,14 +165,23 @@ 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));
|
||||||
const auto str = crashLogPath.u8string();
|
const auto str = crashDumpPath.u8string();
|
||||||
size_t length = str.length();
|
size_t length = str.length();
|
||||||
if (length >= MAX_LONG_PATH)
|
if (length >= MAX_LONG_PATH)
|
||||||
length = MAX_LONG_PATH - 1;
|
length = MAX_LONG_PATH - 1;
|
||||||
strncpy_s(mShm->mStartup.mLogFilePath, sizeof mShm->mStartup.mLogFilePath,
|
strncpy_s(mShm->mStartup.mCrashDumpFilePath, sizeof mShm->mStartup.mCrashDumpFilePath,
|
||||||
Misc::StringUtils::u8StringToString(str).c_str(), length);
|
Misc::StringUtils::u8StringToString(str).c_str(), length);
|
||||||
mShm->mStartup.mLogFilePath[length] = '\0';
|
mShm->mStartup.mCrashDumpFilePath[length] = '\0';
|
||||||
|
|
||||||
|
memset(mShm->mStartup.mFreezeDumpFilePath, 0, sizeof(mShm->mStartup.mFreezeDumpFilePath));
|
||||||
|
const auto strFreeze = freezeDumpPath.u8string();
|
||||||
|
length = strFreeze.length();
|
||||||
|
if (length >= MAX_LONG_PATH)
|
||||||
|
length = MAX_LONG_PATH - 1;
|
||||||
|
strncpy_s(mShm->mStartup.mFreezeDumpFilePath, sizeof mShm->mStartup.mFreezeDumpFilePath,
|
||||||
|
Misc::StringUtils::u8StringToString(strFreeze).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;
|
||||||
@ -204,7 +241,7 @@ namespace Crash
|
|||||||
waitMonitor();
|
waitMonitor();
|
||||||
|
|
||||||
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '"
|
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '"
|
||||||
+ std::string(mShm->mStartup.mLogFilePath)
|
+ std::string(mShm->mStartup.mCrashDumpFilePath)
|
||||||
+ "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
|
+ "'.\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);
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,14 @@ namespace Crash
|
|||||||
class CrashCatcher final
|
class CrashCatcher final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CrashCatcher(int argc, char** argv, const std::filesystem::path& crashLogPath);
|
static CrashCatcher* instance() { return sInstance; }
|
||||||
|
|
||||||
|
CrashCatcher(int argc, char** argv, const std::filesystem::path& crashDumpPath,
|
||||||
|
const std::filesystem::path& freezeDumpPath);
|
||||||
~CrashCatcher();
|
~CrashCatcher();
|
||||||
|
|
||||||
|
void updateDumpPaths(const std::filesystem::path& crashDumpPath, const std::filesystem::path& freezeDumpPath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static CrashCatcher* sInstance;
|
static CrashCatcher* sInstance;
|
||||||
|
|
||||||
@ -54,7 +59,8 @@ namespace Crash
|
|||||||
|
|
||||||
void shmUnlock();
|
void shmUnlock();
|
||||||
|
|
||||||
void startMonitorProcess(const std::filesystem::path& crashLogPath);
|
void startMonitorProcess(
|
||||||
|
const std::filesystem::path& crashDumpPath, const std::filesystem::path& freezeDumpPath);
|
||||||
|
|
||||||
void waitMonitor();
|
void waitMonitor();
|
||||||
|
|
||||||
|
@ -192,7 +192,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:
|
||||||
@ -211,10 +211,10 @@ 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 message = "OpenMW appears to have frozen.\nCrash log saved to '"
|
||||||
+ std::string(mShm->mStartup.mLogFilePath)
|
+ std::string(mShm->mStartup.mFreezeDumpFilePath)
|
||||||
+ "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
|
+ "'.\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);
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ namespace Crash
|
|||||||
return utf16;
|
return utf16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrashMonitor::handleCrash()
|
void CrashMonitor::handleCrash(bool isFreeze)
|
||||||
{
|
{
|
||||||
DWORD processId = GetProcessId(mAppProcessHandle);
|
DWORD processId = GetProcessId(mAppProcessHandle);
|
||||||
|
|
||||||
@ -256,7 +256,8 @@ 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;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ namespace Crash
|
|||||||
|
|
||||||
void shmUnlock();
|
void shmUnlock();
|
||||||
|
|
||||||
void handleCrash();
|
void handleCrash(bool isFreeze);
|
||||||
|
|
||||||
void showFreezeMessageBox();
|
void showFreezeMessageBox();
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -17,6 +17,19 @@
|
|||||||
#include <components/crashcatcher/windows_crashcatcher.hpp>
|
#include <components/crashcatcher/windows_crashcatcher.hpp>
|
||||||
#include <components/files/conversion.hpp>
|
#include <components/files/conversion.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>
|
||||||
@ -301,6 +314,16 @@ void setupLogging(const std::filesystem::path& 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";
|
||||||
|
std::filesystem::path dumpDirectory = logDir;
|
||||||
|
Crash::CrashCatcher::instance()->updateDumpPaths(dumpDirectory / crashDumpName, dumpDirectory / freezeDumpName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName)
|
int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName)
|
||||||
@ -319,9 +342,16 @@ int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, c
|
|||||||
env == nullptr || Misc::StringUtils::toNumeric<int>(env, 0) == 0)
|
env == nullptr || Misc::StringUtils::toNumeric<int>(env, 0) == 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(
|
const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp";
|
||||||
argc, argv, Files::pathToUnicodeString(std::filesystem::temp_directory_path() / crashLogName));
|
std::filesystem::path dumpDirectory = std::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, dumpDirectory / freezeDumpName);
|
||||||
#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.
|
// install the crash handler as soon as possible.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user