Skip to content

Commit 421d5f6

Browse files
Synchronize changes from 1.6 branch [ci skip]
c5fd124 Addendum to 47e0492 bc81c45 Part 4 of "Rewrite crash handler"
2 parents 9dfedf4 + c5fd124 commit 421d5f6

File tree

11 files changed

+711
-484
lines changed

11 files changed

+711
-484
lines changed

Client/core/CCore.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -969,11 +969,7 @@ T* InitModule(CModuleLoader& m_Loader, const SString& strName, const SString& st
969969
}
970970

971971
// If we have a valid initializer, call it.
972-
T* pResult = nullptr;
973-
if (pfnInit != nullptr)
974-
{
975-
pResult = pfnInit(pObj);
976-
}
972+
T* pResult = pfnInit(pObj);
977973

978974
// Restore current directory
979975
SetCurrentDirectory(strSavedCwd);

Client/core/CCrashDumpWriter.cpp

Lines changed: 267 additions & 107 deletions
Large diffs are not rendered by default.

Client/core/CCrashDumpWriter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class CCrashDumpWriter
4242
static long WINAPI HandleExceptionGlobal(_EXCEPTION_POINTERS* pException);
4343
static void DumpCoreLog(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation);
4444
static void DumpMiniDump(_EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation);
45-
static void RunErrorTool(CExceptionInformation* pExceptionInformation);
45+
[[nodiscard]] static bool RunErrorTool(CExceptionInformation* pExceptionInformation);
4646
static void AppendToDumpFile(const SString& strPathFilename, const CBuffer& dataBuffer, DWORD dwMagicStart, DWORD dwMagicEnd);
4747
static void GetPoolInfo(CBuffer& buffer);
4848
static void GetD3DInfo(CBuffer& buffer);

Client/core/CExceptionInformation_Impl.cpp

Lines changed: 78 additions & 92 deletions
Large diffs are not rendered by default.

Client/core/CVersionUpdater.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,8 +3201,8 @@ void CVersionUpdater::_UseCrashDumpQueryURLs()
32013201
return;
32023202
}
32033203

3204-
auto is_control_char = [](const unsigned char c) noexcept -> bool {
3205-
return c < CONTROL_CHAR_THRESHOLD || c == DELETE_CHAR;
3204+
const auto is_control_char = [CONTROL_CHAR_THRESHOLD, DELETE_CHAR](unsigned char c) noexcept -> bool {
3205+
return c < CONTROL_CHAR_THRESHOLD || c == DELETE_CHAR;
32063206
};
32073207

32083208
SString strSanitizedFilename = strFilename;
@@ -3406,14 +3406,14 @@ void CVersionUpdater::_UseCrashDumpPostContent()
34063406
const int iCurrentRetry = GetApplicationSettingInt(DIAGNOSTICS_SECTION, LAST_DUMP_LOAD_RETRY);
34073407

34083408
// Lambda for backoff calculation with explicit return type
3409-
constexpr auto calculate_backoff = [](const int retry_count) constexpr noexcept -> int {
3410-
if (retry_count <= 0)
3411-
return 0;
3412-
int backoff = INITIAL_BACKOFF_SECONDS;
3413-
for (int i = 1; i < retry_count; ++i)
3414-
backoff *= BACKOFF_MULTIPLIER;
3415-
return backoff;
3416-
};
3409+
const auto calculate_backoff = [INITIAL_BACKOFF_SECONDS, BACKOFF_MULTIPLIER](int retry_count) noexcept -> int {
3410+
if (retry_count <= 0)
3411+
return 0;
3412+
int backoff = INITIAL_BACKOFF_SECONDS;
3413+
for (int i = 1; i < retry_count; ++i)
3414+
backoff *= BACKOFF_MULTIPLIER;
3415+
return backoff;
3416+
};
34173417

34183418
// Calculate backoff for current retry
34193419
const int iBackoffSeconds = calculate_backoff(iCurrentRetry);

Client/core/CrashHandler.cpp

Lines changed: 198 additions & 221 deletions
Large diffs are not rendered by default.

Client/core/CrashHandler.h

Lines changed: 99 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
* FILE: core/CrashHandler.h
66
* PURPOSE: Header file for crash handling functions
77
*
8-
* THIS FILE CREDITS: "Debugging Applications" (Microsoft Press) by John Robbins
8+
* THIS FILE CREDITS (IS BASED ON): "Debugging Applications" (Microsoft Press) by John Robbins
9+
* Copyright (c) 1997-2000 John Robbins -- All rights reserved
910
*
1011
* Multi Theft Auto is available from https://www.multitheftauto.com/
1112
*
@@ -15,7 +16,11 @@
1516

1617
#define WIN32_LEAN_AND_MEAN
1718
#include <windows.h>
19+
#include <algorithm>
1820
#include <chrono>
21+
#include <cstdarg>
22+
#include <cstdio>
23+
#include <cstring>
1924
#include <exception>
2025
#include <optional>
2126
#include <string>
@@ -31,6 +36,7 @@
3136
#endif
3237

3338
constexpr std::size_t DEBUG_BUFFER_SIZE = 256;
39+
static_assert(DEBUG_BUFFER_SIZE > 1, "DEBUG_BUFFER_SIZE must allow for null termination");
3440

3541
constexpr DWORD CPP_EXCEPTION_CODE = 0xE06D7363;
3642
constexpr DWORD STATUS_INVALID_CRUNTIME_PARAMETER_CODE = 0xC0000417;
@@ -73,12 +79,25 @@ inline constexpr std::string_view DEBUG_SEPARATOR = "!!!!!!!!!!!!!!!!!!!!!!!!!!!
7379

7480
inline void SafeDebugOutput(std::string_view message) noexcept
7581
{
76-
if (!message.empty() && message.data() != nullptr)
82+
const char* data = message.data();
83+
std::size_t remaining = message.size();
84+
85+
if (data == nullptr || remaining == 0)
7786
{
78-
// string_view from string literal is null-terminated, but views from substrings may not be
79-
// Create temporary null-terminated string for safety with OutputDebugStringA
80-
const std::string temp{message};
81-
OutputDebugStringA(temp.c_str());
87+
return;
88+
}
89+
90+
char buffer[DEBUG_BUFFER_SIZE] = {};
91+
92+
while (remaining > 0)
93+
{
94+
const std::size_t chunkLength = std::min<std::size_t>(remaining, DEBUG_BUFFER_SIZE - 1);
95+
std::memcpy(buffer, data, chunkLength);
96+
buffer[chunkLength] = '\0';
97+
OutputDebugStringA(buffer);
98+
99+
data += chunkLength;
100+
remaining -= chunkLength;
82101
}
83102
}
84103

@@ -100,33 +119,81 @@ inline void SafeDebugOutput(const std::string& message) noexcept
100119
}
101120
}
102121

103-
#define SAFE_DEBUG_PRINT(buffer, format, ...) \
104-
do \
105-
{ \
106-
if ((buffer).data() != nullptr && (buffer).size() > 0) \
107-
{ \
108-
memset((buffer).data(), 0, (buffer).size()); \
109-
int result = _snprintf_s((buffer).data(), (buffer).size(), _TRUNCATE, format, __VA_ARGS__); \
110-
if (result > 0) \
111-
{ \
112-
OutputDebugStringA((buffer).data()); \
113-
} \
114-
} \
115-
} while (false)
116-
117-
#define SAFE_DEBUG_PRINT_C(buffer, bufferSize, format, ...) \
118-
do \
119-
{ \
120-
if (buffer != nullptr && bufferSize > 0) \
121-
{ \
122-
int result = _snprintf_s(buffer, bufferSize, _TRUNCATE, format, __VA_ARGS__); \
123-
if (result > 0) \
124-
{ \
125-
OutputDebugStringA(buffer); \
126-
} \
127-
} \
128-
} while (false)
122+
template <typename Buffer>
123+
inline void SafeDebugPrint(Buffer& buffer, const char* format, ...) noexcept
124+
{
125+
if (format == nullptr)
126+
return;
127+
128+
auto* data = buffer.data();
129+
const std::size_t size = buffer.size();
130+
131+
if (data == nullptr || size == 0)
132+
return;
133+
134+
std::memset(data, 0, size);
135+
136+
va_list args;
137+
va_start(args, format);
138+
const int written = _vsnprintf_s(data, size, _TRUNCATE, format, args);
139+
va_end(args);
140+
141+
if (written > 0)
142+
{
143+
OutputDebugStringA(data);
144+
}
145+
}
146+
147+
inline void SafeDebugPrintC(char* buffer, std::size_t bufferSize, const char* format, ...) noexcept
148+
{
149+
if (buffer == nullptr || bufferSize == 0 || format == nullptr)
150+
return;
151+
152+
va_list args;
153+
va_start(args, format);
154+
const int written = _vsnprintf_s(buffer, bufferSize, _TRUNCATE, format, args);
155+
va_end(args);
156+
157+
if (written > 0)
158+
{
159+
OutputDebugStringA(buffer);
160+
}
161+
}
162+
163+
#define SAFE_DEBUG_PRINT(buffer, ...) SafeDebugPrint((buffer), __VA_ARGS__)
164+
#define SAFE_DEBUG_PRINT_C(buffer, bufferSize, ...) SafeDebugPrintC((buffer), (bufferSize), __VA_ARGS__)
165+
166+
inline void SafeDebugPrintPrefixed(std::string_view prefix, const char* format, ...) noexcept
167+
{
168+
if (format == nullptr)
169+
return;
170+
171+
char buffer[DEBUG_BUFFER_SIZE] = {};
172+
173+
std::size_t offset = 0;
174+
if (!prefix.empty())
175+
{
176+
offset = std::min<std::size_t>(prefix.size(), DEBUG_BUFFER_SIZE - 1);
177+
std::memcpy(buffer, prefix.data(), offset);
178+
}
179+
180+
if (offset >= DEBUG_BUFFER_SIZE - 1)
181+
{
182+
buffer[DEBUG_BUFFER_SIZE - 1] = '\0';
183+
OutputDebugStringA(buffer);
184+
return;
185+
}
129186

187+
va_list args;
188+
va_start(args, format);
189+
const int written = _vsnprintf_s(buffer + offset, DEBUG_BUFFER_SIZE - offset, _TRUNCATE, format, args);
190+
va_end(args);
191+
192+
if (written > 0 || offset > 0)
193+
{
194+
OutputDebugStringA(buffer);
195+
}
196+
}
130197
#ifdef __cplusplus
131198
extern "C"
132199
{

Client/loader/D3DStuff.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "D3DStuff.h"
1212
#include "Utils.h"
1313
#include "Dialogs.h"
14-
#include "../core/CrashHandler.h"
14+
#include "../sdk/core/CrashHandlerExports.h"
1515

1616
#include <atomic>
1717
#include <d3d9.h>

Client/loader/Dialogs.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -648,20 +648,14 @@ void HideCrashedDialog()
648648
{
649649
if (hwndCrashedDialog)
650650
{
651-
try {
652-
if (IsWindow(hwndCrashedDialog))
653-
DestroyWindow(hwndCrashedDialog);
654-
}
655-
catch (...) {
656-
}
657-
(void)std::exchange(hwndCrashedDialog, nullptr);
658-
}
659-
660-
try {
661-
ResumeSplash();
662-
}
663-
catch (...) {
651+
const HWND crashedDialog = hwndCrashedDialog;
652+
hwndCrashedDialog = nullptr;
653+
654+
if (crashedDialog && IsWindow(crashedDialog))
655+
DestroyWindow(crashedDialog);
664656
}
657+
658+
ResumeSplash();
665659
}
666660

667661
void ShowOOMMessageBox([[maybe_unused]] HINSTANCE hInstance)

Client/loader/Main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ MTAEXPORT int DoWinMain(HINSTANCE hLauncherInstance, MAYBE_UNUSED HINSTANCE hPre
288288
// Get current process ID for logging
289289
DWORD currentPid = GetSafeProcessId();
290290

291-
AddReportLog(LOG_ID_END, SString("* End (0x%X)* pid:%d", iReturnCode, currentPid));
292-
291+
const DWORD exitCodeForLog = static_cast<DWORD>(static_cast<unsigned int>(iReturnCode));
292+
AddReportLog(LOG_ID_END, SString("* End (0x%08X)* pid:%lu", exitCodeForLog, static_cast<unsigned long>(currentPid)));
293+
293294
return iReturnCode;
294295
}

0 commit comments

Comments
 (0)