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"
18 #include <sys/utsname.h>
20 #if defined(__GLIBC__)
22 # include <execinfo.h>
24 # include <ucontext.h>
28 #if defined(__NetBSD__)
32 #include "../../safeguards.h"
44 if (uname(&name) < 0) {
45 return buffer +
seprintf(buffer, last,
"Could not get OS version: %s\n", strerror(errno));
48 return buffer +
seprintf(buffer, last,
61 char *
LogError(
char *buffer,
const char *last,
const char *
message)
const override
63 return buffer +
seprintf(buffer, last,
67 strsignal(this->signum),
75 struct StackWalkerParams {
88 static int SunOSStackWalker(uintptr_t pc,
int sig,
void *params)
90 StackWalkerParams *wp = (StackWalkerParams *)params;
94 if (dladdr((
void *)pc, &dli) != 0) {
95 *wp->bufptr +=
seprintf(*wp->bufptr, wp->last,
" [%02i] %s(%s+0x%x) [0x%x]\n",
96 wp->counter, dli.dli_fname, dli.dli_sname, (
int)((
byte *)pc - (
byte *)dli.dli_saddr), (uint)pc);
98 *wp->bufptr +=
seprintf(*wp->bufptr, wp->last,
" [%02i] [0x%x]\n", wp->counter, (uint)pc);
108 buffer +=
seprintf(buffer, last,
"Stacktrace:\n");
109 #if defined(__GLIBC__)
111 int trace_size = backtrace(trace,
lengthof(trace));
113 char **messages = backtrace_symbols(trace, trace_size);
114 for (
int i = 0; i < trace_size; i++) {
115 buffer +=
seprintf(buffer, last,
" [%02i] %s\n", i, messages[i]);
120 if (getcontext(&uc) != 0) {
121 buffer +=
seprintf(buffer, last,
" getcontext() failed\n\n");
125 StackWalkerParams wp = { &buffer, last, 0 };
126 walkcontext(&uc, &CrashLogUnix::SunOSStackWalker, &wp);
128 buffer +=
seprintf(buffer, last,
" Not supported.\n");
130 return buffer +
seprintf(buffer, last,
"\n");
159 printf(
"A serious fault condition occurred in the game. The game will shut down.\n");
160 printf(
"As you loaded an emergency savegame no crash information will be generated.\n");
165 printf(
"A serious fault condition occurred in the game. The game will shut down.\n");
166 printf(
"As you loaded an savegame for which you do not have the required NewGRFs\n");
167 printf(
"no crash information will be generated.\n");
bool MakeCrashLog() const
Makes the crash log, writes it to a file and then subsequently tries to make a crash dump and crash s...
static void AfterCrashLogCleanup()
Try to close the sound/video stuff so it doesn't keep lingering around incorrect video states or so,...
static void CDECL HandleCrash(int signum)
Entry point for the crash handler.
char * LogOSVersion(char *buffer, const char *last) const override
Writes OS' version to the buffer.
char * LogError(char *buffer, const char *last, const char *message) const override
Writes actually encountered error to the buffer.
static const int _signals_to_handle[]
The signals we want our crash handler to handle.
static void InitThread()
Prepare crash log handler for a newly started thread.
bool GamelogTestEmergency()
Finds out if current game is a loaded emergency savegame.
bool SaveloadCrashWithMissingNewGRFs()
Did loading the savegame cause a crash? If so, were NewGRFs missing?
Unix implementation for the crash logger.
static const char * message
Pointer to the error message.
Helper class for creating crash logs.
static void InitialiseCrashLog()
Initialiser for crash logs; do the appropriate things so crashes are handled by our crash handler ins...
#define endof(x)
Get the end element of an fixed size array.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
int signum
Signal that has been thrown.
#define lengthof(x)
Return the length of an fixed size array.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
CrashLogUnix(int signum)
A crash log is always generated by signal.
char * LogStacktrace(char *buffer, const char *last) const override
Writes the stack trace to the buffer, if there is information about it available.