OpenTTD Source
20240917-master-g9ab0a47812
|
Go to the documentation of this file.
10 #include "../../stdafx.h"
11 #include "../../crashlog.h"
12 #include "../../fileio_func.h"
13 #include "../../string_func.h"
14 #include "../../gamelog.h"
15 #include "../../saveload/saveload.h"
16 #include "../../video/video_driver.hpp"
21 #include <mach-o/arch.h>
26 #ifdef WITH_UNOFFICIAL_BREAKPAD
27 # include <client/mac/handler/exception_handler.h>
30 #include "../../safeguards.h"
35 #define IS_ALIGNED(addr) (((uintptr_t)(addr) & 0xf) == 8)
37 #define IS_ALIGNED(addr) (((uintptr_t)(addr) & 0xf) == 0)
40 #define MAX_STACK_FRAMES 64
43 static constexpr
int _signals_to_handle[] = { SIGSEGV, SIGABRT, SIGFPE, SIGBUS, SIGILL, SIGSYS, SIGQUIT };
55 survey[
"reason"] = strsignal(
signum);
61 int trace_size = backtrace(trace,
lengthof(trace));
63 survey = nlohmann::json::array();
65 char **messages = backtrace_symbols(trace, trace_size);
66 for (
int i = 0; i < trace_size; i++) {
67 survey.push_back(messages[i]);
72 #ifdef WITH_UNOFFICIAL_BREAKPAD
73 static bool MinidumpCallback(
const char *dump_dir,
const char *minidump_id,
void *context,
bool succeeded)
78 std::rename(fmt::format(
"{}/{}.dmp", dump_dir, minidump_id).c_str(), crashlog->crashdump_filename.c_str());
84 return google_breakpad::ExceptionHandler::WriteMinidump(
_personal_dir, MinidumpCallback,
this);
88 bool TryExecute(std::string_view section_name, std::function<
bool()> &&func)
override
94 fmt::print(
"Something went wrong when attempting to fill {} section of the crash log.\n", section_name);
102 sigprocmask(SIG_UNBLOCK, &sigs,
nullptr);
123 static const char crash_title[] =
124 "A serious fault condition occurred in the game. The game will shut down.";
126 std::string
message = fmt::format(
127 "Please send crash.json.log, crash.dmp, and crash.sav to the developers. "
128 "This will greatly help debugging.\n\n"
129 "https://github.com/OpenTTD/OpenTTD/issues.\n\n"
131 this->crashlog_filename, this->crashdump_filename, this->savegame_filename, this->screenshot_filename);
159 sigaddset(&sigs, signum);
163 memset(&sa, 0,
sizeof(sa));
164 sa.sa_flags = SA_RESTART;
166 sigemptyset(&sa.sa_mask);
167 sa.sa_handler = handler;
171 sigaction(signum, &sa,
nullptr);
184 fmt::print(
"Something went seriously wrong when creating the crash log. Aborting.\n");
206 sigprocmask(SIG_UNBLOCK, &sigs, &old_sigset);
209 ShowMacDialog(
"A serious fault condition occurred in the game. The game will shut down.",
210 "As you loaded an emergency savegame no crash information will be generated.\n",
216 ShowMacDialog(
"A serious fault condition occurred in the game. The game will shut down.",
217 "As you loaded an savegame for which you do not have the required NewGRFs no crash information will be generated.\n",
OSX implementation for the crash logger.
static void CDECL HandleCrash(int signum)
Entry point for the crash handler.
std::string _personal_dir
custom directory for personal settings, saves, newgrf, etc.
static void AfterCrashLogCleanup()
Try to close the sound/video stuff so it doesn't keep lingering around incorrect video states or so,...
Gamelog _gamelog
Gamelog instance.
void MakeCrashLog()
Makes the crash log, writes it to a file and then subsequently tries to make a crash dump and crash s...
static void CDECL HandleInternalCrash(int)
Entry point for a crash that happened during the handling of a crash.
void SurveyStacktrace(nlohmann::json &survey) const override
Convert stacktrace to JSON.
static sigset_t SetSignals(void(*handler)(int))
Set a signal handler for all signals we want to capture.
bool TestEmergency()
Finds out if current game is a loaded emergency savegame.
static CrashLogOSX * current
Points to the current crash log.
void free(const void *ptr)
Version of the standard free that accepts const pointers.
static void InitThread()
Prepare crash log handler for a newly started thread.
int signum
Signal that has been thrown.
bool SaveloadCrashWithMissingNewGRFs()
Did loading the savegame cause a crash? If so, were NewGRFs missing?
Helper class for creating crash logs.
#define lengthof(array)
Return the length of an fixed size array.
void SurveyCrash(nlohmann::json &survey) const override
Convert system crash reason to JSON.
std::string CreateFileName(const char *ext, bool with_dir=true) const
Create a timestamped filename.
void ShowMacDialog(const char *title, const char *message, const char *button_label)
Helper function displaying a message the best possible way.
static constexpr int _signals_to_handle[]
The signals we want our crash handler to handle.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
static void InitialiseCrashLog()
Initialiser for crash logs; do the appropriate things so crashes are handled by our crash handler ins...
jmp_buf internal_fault_jmp_buf
Buffer to track the long jump set setup.
CrashLogOSX(int signum)
A crash log is always generated by signal.
bool TryExecute(std::string_view section_name, std::function< bool()> &&func) override
Execute the func() and return its value.
void DisplayCrashDialog() const
Show a dialog with the crash information.
static std::string message
Error message coming from #FatalError(format, ...).
virtual bool WriteCrashDump()
Write the (crash) dump to a file.
bool try_execute_active
Whether we are in a TryExecute block.