Skip to content

Commit 3b669c2

Browse files
committed
Merge branch 'nsaids-for-shared-memory-structs-48' into 'openmw-48'
Share the dump directory for crash and freeze dumps for 0.48 See merge request OpenMW/openmw!3222
2 parents 0a593c4 + 33884db commit 3b669c2

8 files changed

+75
-37
lines changed

components/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ if(WIN32)
284284
windows_crashcatcher
285285
windows_crashmonitor
286286
windows_crashshm
287+
windowscrashdumppathhelpers
287288
)
288289
elseif(NOT ANDROID)
289290
add_component_dir (crashcatcher

components/crashcatcher/windows_crashcatcher.cpp

+34-26
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,23 @@
77

88
#include "windows_crashmonitor.hpp"
99
#include "windows_crashshm.hpp"
10+
#include "windowscrashdumppathhelpers.hpp"
1011
#include <SDL_messagebox.h>
1112

1213
namespace Crash
1314
{
15+
namespace
16+
{
17+
template <class T, std::size_t N>
18+
void writePathToShm(T(&buffer)[N], const std::string& path)
19+
{
20+
memset(buffer, 0, sizeof(buffer));
21+
size_t length = path.length();
22+
if (length >= sizeof(buffer))
23+
length = sizeof(buffer) - 1;
24+
strncpy(buffer, path.c_str(), length);
25+
}
26+
}
1427

1528
HANDLE duplicateHandle(HANDLE handle)
1629
{
@@ -26,7 +39,7 @@ namespace Crash
2639

2740
CrashCatcher* CrashCatcher::sInstance = nullptr;
2841

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

@@ -48,7 +61,7 @@ namespace Crash
4861
if (!shmHandle)
4962
{
5063
setupIpc();
51-
startMonitorProcess(crashDumpPath, freezeDumpPath);
64+
startMonitorProcess(dumpPath, crashDumpName, freezeDumpName);
5265
installHandler();
5366
}
5467
else
@@ -75,21 +88,21 @@ namespace Crash
7588
CloseHandle(mShmHandle);
7689
}
7790

78-
void CrashCatcher::updateDumpPaths(const std::string& crashDumpPath, const std::string& freezeDumpPath)
91+
void CrashCatcher::updateDumpPath(const std::string& dumpPath)
7992
{
8093
shmLock();
8194

82-
memset(mShm->mStartup.mCrashDumpFilePath, 0, sizeof(mShm->mStartup.mCrashDumpFilePath));
83-
size_t length = crashDumpPath.length();
84-
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
85-
strncpy(mShm->mStartup.mCrashDumpFilePath, crashDumpPath.c_str(), length);
86-
mShm->mStartup.mCrashDumpFilePath[length] = '\0';
95+
writePathToShm(mShm->mStartup.mDumpDirectoryPath, dumpPath);
96+
97+
shmUnlock();
98+
}
99+
100+
void CrashCatcher::updateDumpNames(const std::string& crashDumpName, const std::string& freezeDumpName)
101+
{
102+
shmLock();
87103

88-
memset(mShm->mStartup.mFreezeDumpFilePath, 0, sizeof(mShm->mStartup.mFreezeDumpFilePath));
89-
length = freezeDumpPath.length();
90-
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
91-
strncpy(mShm->mStartup.mFreezeDumpFilePath, freezeDumpPath.c_str(), length);
92-
mShm->mStartup.mFreezeDumpFilePath[length] = '\0';
104+
writePathToShm(mShm->mStartup.mCrashDumpFileName, crashDumpName);
105+
writePathToShm(mShm->mStartup.mFreezeDumpFileName, freezeDumpName);
93106

94107
shmUnlock();
95108
}
@@ -143,7 +156,7 @@ namespace Crash
143156
SetUnhandledExceptionFilter(vectoredExceptionHandler);
144157
}
145158

146-
void CrashCatcher::startMonitorProcess(const std::string& crashDumpPath, const std::string& freezeDumpPath)
159+
void CrashCatcher::startMonitorProcess(const std::string& dumpPath, const std::string& crashDumpName, const std::string& freezeDumpName)
147160
{
148161
std::wstring executablePath;
149162
DWORD copied = 0;
@@ -153,17 +166,9 @@ namespace Crash
153166
} while (copied >= executablePath.size());
154167
executablePath.resize(copied);
155168

156-
memset(mShm->mStartup.mCrashDumpFilePath, 0, sizeof(mShm->mStartup.mCrashDumpFilePath));
157-
size_t length = crashDumpPath.length();
158-
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
159-
strncpy(mShm->mStartup.mCrashDumpFilePath, crashDumpPath.c_str(), length);
160-
mShm->mStartup.mCrashDumpFilePath[length] = '\0';
161-
162-
memset(mShm->mStartup.mFreezeDumpFilePath, 0, sizeof(mShm->mStartup.mFreezeDumpFilePath));
163-
length = freezeDumpPath.length();
164-
if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1;
165-
strncpy(mShm->mStartup.mFreezeDumpFilePath, freezeDumpPath.c_str(), length);
166-
mShm->mStartup.mFreezeDumpFilePath[length] = '\0';
169+
writePathToShm(mShm->mStartup.mDumpDirectoryPath, dumpPath);
170+
writePathToShm(mShm->mStartup.mCrashDumpFileName, crashDumpName);
171+
writePathToShm(mShm->mStartup.mFreezeDumpFileName, freezeDumpName);
167172

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

194+
CloseHandle(pi.hProcess);
195+
CloseHandle(pi.hThread);
196+
189197
waitMonitor();
190198
}
191199

@@ -222,7 +230,7 @@ namespace Crash
222230
// must remain until monitor has finished
223231
waitMonitor();
224232

225-
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 !";
233+
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 !";
226234
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
227235
}
228236

components/crashcatcher/windows_crashcatcher.hpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ namespace Crash
3232
return sInstance;
3333
}
3434

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

38-
void updateDumpPaths(const std::string& crashDumpPath, const std::string& freezeDumpPath);
38+
void updateDumpPath(const std::string& dumpPath);
39+
40+
void updateDumpNames(const std::string& crashDumpName, const std::string& freezeDumpName);
3941

4042
private:
4143

@@ -62,7 +64,7 @@ namespace Crash
6264

6365
void shmUnlock();
6466

65-
void startMonitorProcess(const std::string& crashDumpPath, const std::string& freezeDumpPath);
67+
void startMonitorProcess(const std::string& dumpPath, const std::string& crashDumpName, const std::string& freezeDumpName);
6668

6769
void waitMonitor();
6870

components/crashcatcher/windows_crashmonitor.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "windows_crashcatcher.hpp"
1414
#include "windows_crashshm.hpp"
15+
#include "windowscrashdumppathhelpers.hpp"
1516
#include <components/debug/debuglog.hpp>
1617

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

@@ -250,7 +251,7 @@ namespace Crash
250251
if (miniDumpWriteDump == NULL)
251252
return;
252253

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

components/crashcatcher/windows_crashshm.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace Crash
88

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

1213
struct CrashSHM
1314
{
@@ -28,8 +29,9 @@ namespace Crash
2829
HANDLE mSignalApp;
2930
HANDLE mSignalMonitor;
3031
HANDLE mShmMutex;
31-
char mCrashDumpFilePath[MAX_LONG_PATH];
32-
char mFreezeDumpFilePath[MAX_LONG_PATH];
32+
char mDumpDirectoryPath[MAX_LONG_PATH];
33+
char mCrashDumpFileName[MAX_FILENAME];
34+
char mFreezeDumpFileName[MAX_FILENAME];
3335
} mStartup;
3436

3537
struct Crashed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "windowscrashdumppathhelpers.hpp"
2+
3+
#include <boost/filesystem/path.hpp>
4+
5+
std::string Crash::getCrashDumpPath(const CrashSHM& crashShm)
6+
{
7+
return (boost::filesystem::path(crashShm.mStartup.mDumpDirectoryPath) / crashShm.mStartup.mCrashDumpFileName).string();
8+
}
9+
10+
std::string Crash::getFreezeDumpPath(const CrashSHM& crashShm)
11+
{
12+
return (boost::filesystem::path(crashShm.mStartup.mDumpDirectoryPath) / crashShm.mStartup.mFreezeDumpFileName).string();
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef COMPONENTS_CRASH_WINDOWSCRASHDUMPPATHHELPERS_H
2+
#include "windows_crashshm.hpp"
3+
4+
#include <string>
5+
6+
namespace Crash
7+
{
8+
std::string getCrashDumpPath(const CrashSHM& crashShm);
9+
10+
std::string getFreezeDumpPath(const CrashSHM& crashShm);
11+
}
12+
13+
#endif

components/debug/debugging.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,8 @@ void setupLogging(const std::string& logDir, std::string_view appName)
300300
#ifdef _WIN32
301301
if (Crash::CrashCatcher::instance())
302302
{
303-
const std::string crashDumpName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp";
304-
const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp";
305303
boost::filesystem::path dumpDirectory(logDir);
306-
Crash::CrashCatcher::instance()->updateDumpPaths((dumpDirectory / crashDumpName).make_preferred().string(), (dumpDirectory / freezeDumpName).make_preferred().string());
304+
Crash::CrashCatcher::instance()->updateDumpPath(dumpDirectory.make_preferred().string());
307305
}
308306
#endif
309307
}
@@ -335,7 +333,7 @@ int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, c
335333
dumpDirectory = userProfile;
336334
}
337335
CoTaskMemFree(userProfile);
338-
Crash::CrashCatcher crashy(argc, argv, (dumpDirectory / crashDumpName).make_preferred().string(), (dumpDirectory / freezeDumpName).make_preferred().string());
336+
Crash::CrashCatcher crashy(argc, argv, dumpDirectory.make_preferred().string(), crashDumpName, freezeDumpName);
339337
#else
340338
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log";
341339
// install the crash handler as soon as possible. note that the log path

0 commit comments

Comments
 (0)