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
55 char *LogOSVersion(
char *buffer,
const char *last)
const
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
74 char *LogError(
char *buffer,
const char *last,
const char *
message)
const
76 return buffer +
seprintf(buffer, last,
82 message == NULL ?
"<none>" : message
86 char *LogStacktrace(
char *buffer,
const char *last)
const
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");
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");
182 printf(
"Writing crash savegame...\n");
188 printf(
"Writing crash savegame...\n");
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",
225 for (
const int *i = _signals_to_handle; i !=
endof(_signals_to_handle); i++) {
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",
253 for (
const int *i = _signals_to_handle; i !=
endof(_signals_to_handle); i++) {