From 76e12c994db35dc582255dff7dadf4029ac7e657 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 25 Apr 2022 18:48:28 +0100 Subject: [PATCH] Crash log: Write log to file and console as it is being generated on Unix --- src/crashlog.cpp | 43 +++++++++++++++++++++++++++++++++++++------ src/crashlog.h | 5 ++++- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 96c3a35ea6..07a16f7c2c 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -432,7 +432,7 @@ char *CrashLog::LogCommandLog(char *buffer, const char *last) const * @param last The last position in the buffer to write to. * @return the position of the \c '\0' character after the buffer. */ -char *CrashLog::FillCrashLog(char *buffer, const char *last) const +char *CrashLog::FillCrashLog(char *buffer, const char *last) { buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n"); @@ -452,10 +452,13 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const } buffer += seprintf(buffer, last, "\n"); + this->FlushCrashLogBuffer(); + buffer = this->LogError(buffer, last, CrashLog::message); #ifdef USE_SCOPE_INFO if (IsMainThread() || IsGameThread()) { + this->FlushCrashLogBuffer(); buffer += WriteScopeLog(buffer, last); } #endif @@ -467,9 +470,13 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const } buffer = this->LogOpenTTDVersion(buffer, last); + this->FlushCrashLogBuffer(); buffer = this->LogStacktrace(buffer, last); + this->FlushCrashLogBuffer(); buffer = this->LogRegisters(buffer, last); + this->FlushCrashLogBuffer(); buffer = this->LogOSVersion(buffer, last); + this->FlushCrashLogBuffer(); buffer = this->LogCompiler(buffer, last); buffer = this->LogOSVersionDetail(buffer, last); buffer = this->LogConfiguration(buffer, last); @@ -643,7 +650,7 @@ bool CrashLog::WriteCrashLog(const char *buffer, char *filename, const char *fil if (file == nullptr) return false; size_t len = strlen(buffer); - size_t written = fwrite(buffer, 1, len, file); + size_t written = (len != 0) ? fwrite(buffer, 1, len, file) : 0; if (crashlog_file) { *crashlog_file = file; @@ -653,6 +660,23 @@ bool CrashLog::WriteCrashLog(const char *buffer, char *filename, const char *fil return len == written; } +void CrashLog::FlushCrashLogBuffer() +{ + if (this->crash_buffer_write == nullptr) return; + + size_t len = strlen(this->crash_buffer_write); + if (len == 0) return; + + if (this->crash_file != nullptr) { + fwrite(this->crash_buffer_write, 1, len, this->crash_file); + fflush(this->crash_file); + } + fwrite(this->crash_buffer_write, 1, len, stdout); + fflush(stdout); + + this->crash_buffer_write += len; +} + /* virtual */ int CrashLog::WriteCrashDump(char *filename, const char *filename_last) const { /* Stub implementation; not all OSes support this. */ @@ -771,18 +795,25 @@ bool CrashLog::MakeCrashLog(char *buffer, const char *last) bool ret = true; printf("Crash encountered, generating crash log...\n"); - this->FillCrashLog(buffer, last); - printf("%s\n", buffer); - printf("Crash log generated.\n\n"); printf("Writing crash log to disk...\n"); - bool bret = this->WriteCrashLog(buffer, filename, lastof(filename), this->name_buffer); + bool bret = this->WriteCrashLog("", filename, lastof(filename), this->name_buffer, &(this->crash_file)); if (bret) { printf("Crash log written to %s. Please add this file to any bug reports.\n\n", filename); } else { printf("Writing crash log failed. Please attach the output above to any bug reports.\n\n"); ret = false; } + this->crash_buffer_write = buffer; + + this->FillCrashLog(buffer, last); + this->FlushCrashLogBuffer(); + if (this->crash_file != nullptr) { + FioFCloseFile(this->crash_file); + this->crash_file = nullptr; + } + printf("Crash log generated.\n\n"); + /* Don't mention writing crash dumps because not all platforms support it. */ int dret = this->WriteCrashDump(filename, lastof(filename)); diff --git a/src/crashlog.h b/src/crashlog.h index 176fe832f9..f9c38fca46 100644 --- a/src/crashlog.h +++ b/src/crashlog.h @@ -131,11 +131,14 @@ protected: public: /** Buffer for the filename name prefix */ char name_buffer[64]; + FILE *crash_file = nullptr; + const char *crash_buffer_write = nullptr; /** Stub destructor to silence some compilers. */ virtual ~CrashLog() {} - char *FillCrashLog(char *buffer, const char *last) const; + char *FillCrashLog(char *buffer, const char *last); + void FlushCrashLogBuffer(); char *FillDesyncCrashLog(char *buffer, const char *last, const DesyncExtraInfo &info) const; char *FillInconsistencyLog(char *buffer, const char *last, const InconsistencyExtraInfo &info) const; char *FillVersionInfoLog(char *buffer, const char *last) const;