12 #include "../../stdafx.h" 13 #include "../../crashlog.h" 14 #include "../../string_func.h" 15 #include "../../gamelog.h" 16 #include "../../saveload/saveload.h" 21 #include <mach-o/arch.h> 25 #include "../../safeguards.h" 30 #define IS_ALIGNED(addr) (((uintptr_t)(addr) & 0xf) == 8) 32 #define IS_ALIGNED(addr) (((uintptr_t)(addr) & 0xf) == 0) 37 #define PRINTF_PTR "0x%016lx" 39 #define PRINTF_PTR "0x%08lx" 42 #define MAX_STACK_FRAMES 64 57 int ver_maj, ver_min, ver_bug;
58 GetMacOSVersion(&ver_maj, &ver_min, &ver_bug);
60 const NXArchInfo *arch = NXGetLocalArchInfo();
62 return buffer +
seprintf(buffer, last,
65 " Release: %d.%d.%d\n" 68 ver_maj, ver_min, ver_bug,
69 arch != NULL ? arch->description :
"unknown",
70 MAC_OS_X_VERSION_MIN_REQUIRED
76 return buffer +
seprintf(buffer, last,
80 strsignal(this->signum),
82 message == NULL ?
"<none>" : message
92 buffer +=
seprintf(buffer, last,
"\nStacktrace:\n");
95 #if defined(__ppc__) || defined(__ppc64__) 97 __asm__
volatile(
"mr %0, r1" :
"=r" (frame));
99 frame = (
void **)__builtin_frame_address(0);
102 for (
int i = 0; frame != NULL && i < MAX_STACK_FRAMES; i++) {
104 #if defined(__ppc__) || defined(__ppc64__) 109 if (ip == NULL)
break;
112 buffer +=
seprintf(buffer, last,
" [%02d]", i);
115 bool dl_valid = dladdr(ip, &dli) != 0;
117 const char *fname =
"???";
118 if (dl_valid && dli.dli_fname) {
120 const char *s = strrchr(dli.dli_fname,
'/');
124 fname = dli.dli_fname;
128 buffer +=
seprintf(buffer, last,
" %-20s " PRINTF_PTR, fname, (uintptr_t)ip);
131 if (dl_valid && dli.dli_sname != NULL && dli.dli_saddr != NULL) {
134 char *func_name = abi::__cxa_demangle(dli.dli_sname, NULL, 0, &status);
136 long int offset = (intptr_t)ip - (intptr_t)dli.dli_saddr;
137 buffer +=
seprintf(buffer, last,
" (%s + %ld)", func_name != NULL ? func_name : dli.dli_sname, offset);
141 buffer +=
seprintf(buffer, last,
"\n");
144 void **next = (
void **)frame[0];
146 if (next <= frame || !IS_ALIGNED(next))
break;
150 return buffer +
seprintf(buffer, last,
"\n");
160 filename_log[0] =
'\0';
161 filename_save[0] =
'\0';
162 filename_screenshot[0] =
'\0';
171 printf(
"Crash encountered, generating crash log...\n");
173 printf(
"%s\n", buffer);
174 printf(
"Crash log generated.\n\n");
176 printf(
"Writing crash log to disk...\n");
178 filename_log[0] =
'\0';
182 printf(
"Writing crash savegame...\n");
184 filename_save[0] =
'\0';
188 printf(
"Writing crash savegame...\n");
190 filename_screenshot[0] =
'\0';
200 static const char crash_title[] =
201 "A serious fault condition occurred in the game. The game will shut down.";
205 "Please send the generated crash information and the last (auto)save to the developers. " 206 "This will greatly help debugging. The correct place to do this is http://bugs.openttd.org.\n\n" 207 "Generated file(s):\n%s\n%s\n%s",
208 this->filename_log, this->filename_save, this->filename_screenshot);
230 ShowMacDialog(
"A serious fault condition occurred in the game. The game will shut down.",
231 "As you loaded an emergency savegame no crash information will be generated.\n",
237 ShowMacDialog(
"A serious fault condition occurred in the game. The game will shut down.",
238 "As you loaded an savegame for which you do not have the required NewGRFs no crash information will be generated.\n",
bool GamelogTestEmergency()
Finds out if current game is a loaded emergency savegame.
Helper class for creating crash logs.
char filename_save[MAX_PATH]
Path of crash.sav.
bool WriteCrashLog(const char *buffer, char *filename, const char *filename_last) const
Write the crash log to a file.
bool MakeCrashLog()
Generate the crash log.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
char * LogStacktrace(char *buffer, const char *last) const
Writes the stack trace to the buffer, if there is information about it available. ...
void CDECL HandleCrash(int signum)
Entry point for the crash handler.
#define lastof(x)
Get the last element of an fixed size array.
static void InitialiseCrashLog()
Initialiser for crash logs; do the appropriate things so crashes are handled by our crash handler ins...
char filename_screenshot[MAX_PATH]
Path of crash.(png|bmp|pcx)
int signum
Signal that has been thrown.
static const char * message
Pointer to the error message.
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.
static const int _signals_to_handle[]
The signals we want our crash handler to handle.
bool WriteSavegame(char *filename, const char *filename_last) const
Write the (crash) savegame to a file.
OSX implementation for the crash logger.
void DisplayCrashDialog() const
Show a dialog with the crash information.
CrashLogOSX(int signum)
A crash log is always generated by signal.
#define endof(x)
Get the end element of an fixed size array.
void ShowMacDialog(const char *title, const char *message, const char *button_label)
Helper function displaying a message the best possible way.
Functions related to MacOS support.
char * LogOSVersion(char *buffer, const char *last) const
Writes OS' version to the buffer.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
bool SaveloadCrashWithMissingNewGRFs()
Did loading the savegame cause a crash? If so, were NewGRFs missing?
char * FillCrashLog(char *buffer, const char *last) const
Fill the crash log buffer with all data of a crash log.
char * LogError(char *buffer, const char *last, const char *message) const
Writes actually encountered error to the buffer.
char filename_log[MAX_PATH]
Path of crash.log.