diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 37b01449c1..bda0d4d9ef 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -86,6 +86,7 @@ /* static */ const char *CrashLog::message = nullptr; /* static */ char *CrashLog::gamelog_buffer = nullptr; /* static */ const char *CrashLog::gamelog_last = nullptr; +/* static */ bool CrashLog::have_crashed = false; char *CrashLog::LogCompiler(char *buffer, const char *last) const { @@ -921,9 +922,8 @@ static bool CopyAutosave(const std::string &old_name, const std::string &new_nam bool CrashLog::MakeCrashLog(char *buffer, const char *last) { /* Don't keep looping logging crashes. */ - static bool crashlogged = false; - if (crashlogged) return false; - crashlogged = true; + if (CrashLog::HaveAlreadyCrashed()) return false; + CrashLog::RegisterCrashed(); char *name_buffer_date = this->name_buffer + seprintf(this->name_buffer, lastof(this->name_buffer), "crash-"); UTCTime::Format(name_buffer_date, lastof(this->name_buffer), "%Y%m%dT%H%M%SZ"); diff --git a/src/crashlog.h b/src/crashlog.h index 3d59860941..7af22007ba 100644 --- a/src/crashlog.h +++ b/src/crashlog.h @@ -55,6 +55,9 @@ private: /** Temporary 'local' location of the end of the buffer. */ static const char *gamelog_last; + /** Whether a crash has already occured */ + static bool have_crashed; + static void GamelogFillCrashLog(const char *s); protected: /** @@ -208,6 +211,8 @@ public: static void InconsistencyLog(const InconsistencyExtraInfo &info); static void VersionInfoLog(); + static void RegisterCrashed() { CrashLog::have_crashed = true; } + static bool HaveAlreadyCrashed() { return CrashLog::have_crashed; } static void SetErrorMessage(const char *message); static void AfterCrashLogCleanup(); diff --git a/src/openttd.cpp b/src/openttd.cpp index b69874d752..cdfa4af13d 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -168,6 +168,8 @@ void CDECL usererror(const char *s, ...) */ void CDECL error(const char *s, ...) { + if (CrashLog::HaveAlreadyCrashed()) DoOSAbort(); + va_list va; char buf[2048]; @@ -186,6 +188,8 @@ void CDECL error(const char *s, ...) void CDECL assert_msg_error(int line, const char *file, const char *expr, const char *extra, const char *str, ...) { + if (CrashLog::HaveAlreadyCrashed()) DoOSAbort(); + va_list va; char buf[2048]; @@ -200,7 +204,9 @@ void CDECL assert_msg_error(int line, const char *file, const char *expr, const vseprintf(b, lastof(buf), str, va); va_end(va); - ShowOSErrorBox(buf, true); + if (VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) { + ShowOSErrorBox(buf, true); + } /* Set the error message for the crash log and then invoke it. */ CrashLog::SetErrorMessage(buf); diff --git a/src/os/macosx/crashlog_osx.cpp b/src/os/macosx/crashlog_osx.cpp index 1dc1321674..64ba172d9b 100644 --- a/src/os/macosx/crashlog_osx.cpp +++ b/src/os/macosx/crashlog_osx.cpp @@ -486,6 +486,8 @@ static const int _signals_to_handle[] = { SIGSEGV, SIGABRT, SIGFPE, SIGBUS, SIGI */ void CDECL HandleCrash(int signum, siginfo_t *si, void *context) { + CrashLog::RegisterCrashed(); + /* Disable all handling of signals by us, so we don't go into infinite loops. */ for (const int *i = _signals_to_handle; i != endof(_signals_to_handle); i++) { signal(*i, SIG_DFL); diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 648edc2bcd..e7efdd64bd 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -762,6 +762,8 @@ thread_local void *_safe_esp = nullptr; static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) { + CrashLog::RegisterCrashed(); + /* Restore system timer resolution. */ timeEndPeriod(1);