12 #include "../../stdafx.h" 13 #include "../../crashlog.h" 14 #include "../../string_func.h" 15 #include "../../gamelog.h" 16 #include "../../saveload/saveload.h" 20 #include <sys/utsname.h> 22 #if defined(__GLIBC__) 24 # include <execinfo.h> 26 # include <ucontext.h> 30 #if defined(__NetBSD__) 34 #include "../../safeguards.h" 46 if (uname(&name) < 0) {
47 return buffer +
seprintf(buffer, last,
"Could not get OS version: %s\n", strerror(errno));
50 return buffer +
seprintf(buffer, last,
65 return buffer +
seprintf(buffer, last,
69 strsignal(this->signum),
71 message == NULL ?
"<none>" : message
77 struct StackWalkerParams {
90 static int SunOSStackWalker(uintptr_t pc,
int sig,
void *params)
92 StackWalkerParams *wp = (StackWalkerParams *)params;
96 if (dladdr((
void *)pc, &dli) != 0) {
97 *wp->bufptr +=
seprintf(*wp->bufptr, wp->last,
" [%02i] %s(%s+0x%x) [0x%x]\n",
98 wp->counter, dli.dli_fname, dli.dli_sname, (
int)((byte *)pc - (byte *)dli.dli_saddr), (uint)pc);
100 *wp->bufptr +=
seprintf(*wp->bufptr, wp->last,
" [%02i] [0x%x]\n", wp->counter, (uint)pc);
110 buffer +=
seprintf(buffer, last,
"Stacktrace:\n");
111 #if defined(__GLIBC__) 113 int trace_size = backtrace(trace,
lengthof(trace));
115 char **messages = backtrace_symbols(trace, trace_size);
116 for (
int i = 0; i < trace_size; i++) {
117 buffer +=
seprintf(buffer, last,
" [%02i] %s\n", i, messages[i]);
122 if (getcontext(&uc) != 0) {
123 buffer +=
seprintf(buffer, last,
" getcontext() failed\n\n");
127 StackWalkerParams wp = { &buffer, last, 0 };
128 walkcontext(&uc, &CrashLogUnix::SunOSStackWalker, &wp);
130 buffer +=
seprintf(buffer, last,
" Not supported.\n");
132 return buffer +
seprintf(buffer, last,
"\n");
161 printf(
"A serious fault condition occurred in the game. The game will shut down.\n");
162 printf(
"As you loaded an emergency savegame no crash information will be generated.\n");
167 printf(
"A serious fault condition occurred in the game. The game will shut down.\n");
168 printf(
"As you loaded an savegame for which you do not have the required NewGRFs\n");
169 printf(
"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.
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. ...
static void CDECL HandleCrash(int signum)
Entry point for the crash handler.
static void InitialiseCrashLog()
Initialiser for crash logs; do the appropriate things so crashes are handled by our crash handler ins...
static const int _signals_to_handle[]
The signals we want our crash handler to handle.
char * LogError(char *buffer, const char *last, const char *message) const
Writes actually encountered error to the buffer.
CrashLogUnix(int signum)
A crash log is always generated by signal.
static const char * message
Pointer to the error message.
Unix implementation for the crash logger.
static void AfterCrashLogCleanup()
Try to close the sound/video stuff so it doesn't keep lingering around incorrect video states or so...
bool MakeCrashLog() const
Makes the crash log, writes it to a file and then subsequently tries to make a crash dump and crash s...
#define lengthof(x)
Return the length of an fixed size array.
#define endof(x)
Get the end element of an fixed size array.
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?
int signum
Signal that has been thrown.
char * LogOSVersion(char *buffer, const char *last) const
Writes OS' version to the buffer.