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++) {