Skip to content

Commit

Permalink
Merge branch 'nsaids-for-shared-memory-structs-48' into 'openmw-48'
Browse files Browse the repository at this point in the history
Share the dump directory for crash and freeze dumps for 0.48

See merge request OpenMW/openmw!3222
  • Loading branch information
psi29a committed Jul 13, 2023
2 parents 0a593c4 + 33884db commit 3b669c2
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 37 deletions.
1 change: 1 addition & 0 deletions components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ if(WIN32)
windows_crashcatcher
windows_crashmonitor
windows_crashshm
windowscrashdumppathhelpers
)
elseif(NOT ANDROID)
add_component_dir (crashcatcher
Expand Down
60 changes: 34 additions & 26 deletions components/crashcatcher/windows_crashcatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,23 @@

#include "windows_crashmonitor.hpp"
#include "windows_crashshm.hpp"
#include "windowscrashdumppathhelpers.hpp"
#include <SDL_messagebox.h>

namespace Crash
{
namespace
{
template <class T, std::size_t N>
void writePathToShm(T(&buffer)[N], const std::string& path)
{
memset(buffer, 0, sizeof(buffer));
size_t length = path.length();
if (length >= sizeof(buffer))
length = sizeof(buffer) - 1;
strncpy(buffer, path.c_str(), length);
}
}

HANDLE duplicateHandle(HANDLE handle)
{
Expand All @@ -26,7 +39,7 @@ namespace Crash

CrashCatcher* CrashCatcher::sInstance = nullptr;

CrashCatcher::CrashCatcher(int argc, char** argv, const std::string& crashDumpPath, const std::string& freezeDumpPath)
CrashCatcher::CrashCatcher(int argc, char** argv, const std::string& dumpPath, const std::string& crashDumpName, const std::string& freezeDumpName)
{
assert(sInstance == nullptr); // don't allow two instances

Expand All @@ -48,7 +61,7 @@ namespace Crash
if (!shmHandle)
{
setupIpc();
startMonitorProcess(crashDumpPath, freezeDumpPath);
startMonitorProcess(dumpPath, crashDumpName, freezeDumpName);
installHandler();
}
else
Expand All @@ -75,21 +88,21 @@ namespace Crash
CloseHandle(mShmHandle);
}

void CrashCatcher::updateDumpPaths(const std::string& crashDumpPath, const std::string& freezeDumpPath)
void CrashCatcher::updateDumpPath(const std::string& dumpPath)
{
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';
writePathToShm(mShm->mStartup.mDumpDirectoryPath, dumpPath);

shmUnlock();
}

void CrashCatcher::updateDumpNames(const std::string& crashDumpName, const std::string& freezeDumpName)
{
shmLock();

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';
writePathToShm(mShm->mStartup.mCrashDumpFileName, crashDumpName);
writePathToShm(mShm->mStartup.mFreezeDumpFileName, freezeDumpName);

shmUnlock();
}
Expand Down Expand Up @@ -143,7 +156,7 @@ namespace Crash
SetUnhandledExceptionFilter(vectoredExceptionHandler);
}

void CrashCatcher::startMonitorProcess(const std::string& crashDumpPath, const std::string& freezeDumpPath)
void CrashCatcher::startMonitorProcess(const std::string& dumpPath, const std::string& crashDumpName, const std::string& freezeDumpName)
{
std::wstring executablePath;
DWORD copied = 0;
Expand All @@ -153,17 +166,9 @@ namespace Crash
} while (copied >= executablePath.size());
executablePath.resize(copied);

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';
writePathToShm(mShm->mStartup.mDumpDirectoryPath, dumpPath);
writePathToShm(mShm->mStartup.mCrashDumpFileName, crashDumpName);
writePathToShm(mShm->mStartup.mFreezeDumpFileName, freezeDumpName);

// note that we don't need to lock the SHM here, the other process has not started yet
mShm->mEvent = CrashSHM::Event::Startup;
Expand All @@ -186,6 +191,9 @@ namespace Crash
if (!CreateProcessW(executablePath.data(), arguments.data(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
throw std::runtime_error("Could not start crash monitor process");

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

waitMonitor();
}

Expand Down Expand Up @@ -222,7 +230,7 @@ namespace Crash
// must remain until monitor has finished
waitMonitor();

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 !";
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + getCrashDumpPath(*mShm) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
}

Expand Down
8 changes: 5 additions & 3 deletions components/crashcatcher/windows_crashcatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ namespace Crash
return sInstance;
}

CrashCatcher(int argc, char** argv, const std::string& crashDumpPath, const std::string& freezeDumpPath);
CrashCatcher(int argc, char** argv, const std::string& dumpPath, const std::string& crashDumpName, const std::string& freezeDumpName);
~CrashCatcher();

void updateDumpPaths(const std::string& crashDumpPath, const std::string& freezeDumpPath);
void updateDumpPath(const std::string& dumpPath);

void updateDumpNames(const std::string& crashDumpName, const std::string& freezeDumpName);

private:

Expand All @@ -62,7 +64,7 @@ namespace Crash

void shmUnlock();

void startMonitorProcess(const std::string& crashDumpPath, const std::string& freezeDumpPath);
void startMonitorProcess(const std::string& dumpPath, const std::string& crashDumpName, const std::string& freezeDumpName);

void waitMonitor();

Expand Down
5 changes: 3 additions & 2 deletions components/crashcatcher/windows_crashmonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "windows_crashcatcher.hpp"
#include "windows_crashshm.hpp"
#include "windowscrashdumppathhelpers.hpp"
#include <components/debug/debuglog.hpp>

namespace Crash
Expand Down Expand Up @@ -207,7 +208,7 @@ namespace Crash
{
handleCrash(true);
TerminateProcess(mAppProcessHandle, 0xDEAD);
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 !";
std::string message = "OpenMW appears to have frozen.\nCrash log saved to '" + getFreezeDumpPath(*mShm) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
}

Expand Down Expand Up @@ -250,7 +251,7 @@ namespace Crash
if (miniDumpWriteDump == NULL)
return;

std::wstring utf16Path = utf8ToUtf16(isFreeze ? mShm->mStartup.mFreezeDumpFilePath : mShm->mStartup.mCrashDumpFilePath);
std::wstring utf16Path = utf8ToUtf16(isFreeze ? getFreezeDumpPath(*mShm) : getCrashDumpPath(*mShm));
if (utf16Path.empty())
return;

Expand Down
6 changes: 4 additions & 2 deletions components/crashcatcher/windows_crashshm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Crash

// Used to communicate between the app and the monitor, fields are is overwritten with each event.
static constexpr const int MAX_LONG_PATH = 0x7fff;
static constexpr const int MAX_FILENAME = 0xff;

struct CrashSHM
{
Expand All @@ -28,8 +29,9 @@ namespace Crash
HANDLE mSignalApp;
HANDLE mSignalMonitor;
HANDLE mShmMutex;
char mCrashDumpFilePath[MAX_LONG_PATH];
char mFreezeDumpFilePath[MAX_LONG_PATH];
char mDumpDirectoryPath[MAX_LONG_PATH];
char mCrashDumpFileName[MAX_FILENAME];
char mFreezeDumpFileName[MAX_FILENAME];
} mStartup;

struct Crashed
Expand Down
13 changes: 13 additions & 0 deletions components/crashcatcher/windowscrashdumppathhelpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "windowscrashdumppathhelpers.hpp"

#include <boost/filesystem/path.hpp>

std::string Crash::getCrashDumpPath(const CrashSHM& crashShm)
{
return (boost::filesystem::path(crashShm.mStartup.mDumpDirectoryPath) / crashShm.mStartup.mCrashDumpFileName).string();
}

std::string Crash::getFreezeDumpPath(const CrashSHM& crashShm)
{
return (boost::filesystem::path(crashShm.mStartup.mDumpDirectoryPath) / crashShm.mStartup.mFreezeDumpFileName).string();
}
13 changes: 13 additions & 0 deletions components/crashcatcher/windowscrashdumppathhelpers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef COMPONENTS_CRASH_WINDOWSCRASHDUMPPATHHELPERS_H
#include "windows_crashshm.hpp"

#include <string>

namespace Crash
{
std::string getCrashDumpPath(const CrashSHM& crashShm);

std::string getFreezeDumpPath(const CrashSHM& crashShm);
}

#endif
6 changes: 2 additions & 4 deletions components/debug/debugging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,8 @@ void setupLogging(const std::string& logDir, std::string_view appName)
#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());
Crash::CrashCatcher::instance()->updateDumpPath(dumpDirectory.make_preferred().string());
}
#endif
}
Expand Down Expand Up @@ -335,7 +333,7 @@ int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, c
dumpDirectory = userProfile;
}
CoTaskMemFree(userProfile);
Crash::CrashCatcher crashy(argc, argv, (dumpDirectory / crashDumpName).make_preferred().string(), (dumpDirectory / freezeDumpName).make_preferred().string());
Crash::CrashCatcher crashy(argc, argv, dumpDirectory.make_preferred().string(), crashDumpName, freezeDumpName);
#else
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log";
// install the crash handler as soon as possible. note that the log path
Expand Down

0 comments on commit 3b669c2

Please sign in to comment.