OpenTTD Source
1.11.0-beta2
|
Go to the documentation of this file.
10 #include "../../stdafx.h"
11 #include "../../crashlog.h"
12 #include "../../string_func.h"
13 #include "../../gamelog.h"
14 #include "../../saveload/saveload.h"
15 #include "../../video/video_driver.hpp"
20 #include <mach-o/arch.h>
24 #include "../../safeguards.h"
29 #define IS_ALIGNED(addr) (((uintptr_t)(addr) & 0xf) == 8)
31 #define IS_ALIGNED(addr) (((uintptr_t)(addr) & 0xf) == 0)
36 #define PRINTF_PTR "0x%016lx"
38 #define PRINTF_PTR "0x%08lx"
41 #define MAX_STACK_FRAMES 64
56 int ver_maj, ver_min, ver_bug;
57 GetMacOSVersion(&ver_maj, &ver_min, &ver_bug);
59 const NXArchInfo *arch = NXGetLocalArchInfo();
61 return buffer +
seprintf(buffer, last,
64 " Release: %d.%d.%d\n"
68 ver_maj, ver_min, ver_bug,
69 arch !=
nullptr ? arch->description :
"unknown",
70 MAC_OS_X_VERSION_MIN_REQUIRED,
71 MAC_OS_X_VERSION_MAX_ALLOWED
75 char *
LogError(
char *buffer,
const char *last,
const char *
message)
const override
77 return buffer +
seprintf(buffer, last,
81 strsignal(this->signum),
93 buffer +=
seprintf(buffer, last,
"\nStacktrace:\n");
96 #if defined(__ppc__) || defined(__ppc64__)
98 __asm__
volatile(
"mr %0, r1" :
"=r" (frame));
100 frame = (
void **)__builtin_frame_address(0);
103 for (
int i = 0; frame !=
nullptr && i < MAX_STACK_FRAMES; i++) {
105 #if defined(__ppc__) || defined(__ppc64__)
110 if (ip ==
nullptr)
break;
113 buffer +=
seprintf(buffer, last,
" [%02d]", i);
116 bool dl_valid = dladdr(ip, &dli) != 0;
118 const char *fname =
"???";
119 if (dl_valid && dli.dli_fname) {
121 const char *s = strrchr(dli.dli_fname,
'/');
125 fname = dli.dli_fname;
129 buffer +=
seprintf(buffer, last,
" %-20s " PRINTF_PTR, fname, (uintptr_t)ip);
132 if (dl_valid && dli.dli_sname !=
nullptr && dli.dli_saddr !=
nullptr) {
135 char *func_name = abi::__cxa_demangle(dli.dli_sname,
nullptr, 0, &status);
137 long int offset = (intptr_t)ip - (intptr_t)dli.dli_saddr;
138 buffer +=
seprintf(buffer, last,
" (%s + %ld)", func_name !=
nullptr ? func_name : dli.dli_sname, offset);
142 buffer +=
seprintf(buffer, last,
"\n");
145 void **next = (
void **)frame[0];
147 if (next <= frame || !IS_ALIGNED(next))
break;
151 return buffer +
seprintf(buffer, last,
"\n");
172 printf(
"Crash encountered, generating crash log...\n");
174 printf(
"%s\n", buffer);
175 printf(
"Crash log generated.\n\n");
177 printf(
"Writing crash log to disk...\n");
183 printf(
"Writing crash savegame...\n");
189 printf(
"Writing crash savegame...\n");
201 static const char crash_title[] =
202 "A serious fault condition occurred in the game. The game will shut down.";
206 "Please send the generated crash information and the last (auto)save to the developers. "
207 "This will greatly help debugging. The correct place to do this is https://github.com/OpenTTD/OpenTTD/issues.\n\n"
208 "Generated file(s):\n%s\n%s\n%s",
209 this->filename_log, this->filename_save, this->filename_screenshot);
231 ShowMacDialog(
"A serious fault condition occurred in the game. The game will shut down.",
232 "As you loaded an emergency savegame no crash information will be generated.\n",
238 ShowMacDialog(
"A serious fault condition occurred in the game. The game will shut down.",
239 "As you loaded an savegame for which you do not have the required NewGRFs no crash information will be generated.\n",
char filename_save[MAX_PATH]
Path of crash.sav.
OSX implementation for the crash logger.
char filename_log[MAX_PATH]
Path of crash.log.
bool MakeCrashLog()
Generate the crash log.
void CDECL HandleCrash(int signum)
Entry point for the crash handler.
static void AfterCrashLogCleanup()
Try to close the sound/video stuff so it doesn't keep lingering around incorrect video states or so,...
bool WriteScreenshot(char *filename, const char *filename_last) const
Write the (crash) screenshot to a file.
char * LogStacktrace(char *buffer, const char *last) const override
Writes the stack trace to the buffer, if there is information about it available.
char filename_screenshot[MAX_PATH]
Path of crash.(png|bmp|pcx)
static const int _signals_to_handle[]
The signals we want our crash handler to handle.
bool GamelogTestEmergency()
Finds out if current game is a loaded emergency savegame.
int signum
Signal that has been thrown.
bool SaveloadCrashWithMissingNewGRFs()
Did loading the savegame cause a crash? If so, were NewGRFs missing?
static const char * message
Pointer to the error message.
Helper class for creating crash logs.
char * LogOSVersion(char *buffer, const char *last) const override
Writes OS' version to the buffer.
void ShowMacDialog(const char *title, const char *message, const char *button_label)
Helper function displaying a message the best possible way.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
char * LogError(char *buffer, const char *last, const char *message) const override
Writes actually encountered error to the buffer.
static void InitialiseCrashLog()
Initialiser for crash logs; do the appropriate things so crashes are handled by our crash handler ins...
bool WriteSavegame(char *filename, const char *filename_last) const
Write the (crash) savegame to a file.
#define endof(x)
Get the end element of an fixed size array.
CrashLogOSX(int signum)
A crash log is always generated by signal.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
void DisplayCrashDialog() const
Show a dialog with the crash information.
char * FillCrashLog(char *buffer, const char *last) const
Fill the crash log buffer with all data of a crash log.
bool WriteCrashLog(const char *buffer, char *filename, const char *filename_last) const
Write the crash log to a file.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
#define lastof(x)
Get the last element of an fixed size array.