Crash log: Write out crash log incrementally on Windows, MacOS
This commit is contained in:
@@ -796,12 +796,23 @@ void CrashLog::FlushCrashLogBuffer()
|
|||||||
fwrite(this->crash_buffer_write, 1, len, this->crash_file);
|
fwrite(this->crash_buffer_write, 1, len, this->crash_file);
|
||||||
fflush(this->crash_file);
|
fflush(this->crash_file);
|
||||||
}
|
}
|
||||||
|
#if !defined(_WIN32)
|
||||||
fwrite(this->crash_buffer_write, 1, len, stdout);
|
fwrite(this->crash_buffer_write, 1, len, stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
this->crash_buffer_write += len;
|
this->crash_buffer_write += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CrashLog::CloseCrashLogFile()
|
||||||
|
{
|
||||||
|
this->FlushCrashLogBuffer();
|
||||||
|
if (this->crash_file != nullptr) {
|
||||||
|
FioFCloseFile(this->crash_file);
|
||||||
|
this->crash_file = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* virtual */ int CrashLog::WriteCrashDump(char *filename, const char *filename_last) const
|
/* virtual */ int CrashLog::WriteCrashDump(char *filename, const char *filename_last) const
|
||||||
{
|
{
|
||||||
/* Stub implementation; not all OSes support this. */
|
/* Stub implementation; not all OSes support this. */
|
||||||
@@ -954,11 +965,7 @@ bool CrashLog::MakeCrashLog(char *buffer, const char *last)
|
|||||||
this->crash_buffer_write = buffer;
|
this->crash_buffer_write = buffer;
|
||||||
|
|
||||||
this->FillCrashLog(buffer, last);
|
this->FillCrashLog(buffer, last);
|
||||||
this->FlushCrashLogBuffer();
|
this->CloseCrashLogFile();
|
||||||
if (this->crash_file != nullptr) {
|
|
||||||
FioFCloseFile(this->crash_file);
|
|
||||||
this->crash_file = nullptr;
|
|
||||||
}
|
|
||||||
printf("Crash log generated.\n\n");
|
printf("Crash log generated.\n\n");
|
||||||
|
|
||||||
|
|
||||||
|
@@ -162,6 +162,7 @@ public:
|
|||||||
|
|
||||||
char *FillCrashLog(char *buffer, const char *last);
|
char *FillCrashLog(char *buffer, const char *last);
|
||||||
void FlushCrashLogBuffer();
|
void FlushCrashLogBuffer();
|
||||||
|
void CloseCrashLogFile();
|
||||||
char *FillDesyncCrashLog(char *buffer, const char *last, const DesyncExtraInfo &info) const;
|
char *FillDesyncCrashLog(char *buffer, const char *last, const DesyncExtraInfo &info) const;
|
||||||
char *FillInconsistencyLog(char *buffer, const char *last, const InconsistencyExtraInfo &info) const;
|
char *FillInconsistencyLog(char *buffer, const char *last, const InconsistencyExtraInfo &info) const;
|
||||||
char *FillVersionInfoLog(char *buffer, const char *last) const;
|
char *FillVersionInfoLog(char *buffer, const char *last) const;
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "../../debug.h"
|
#include "../../debug.h"
|
||||||
#include "../../video/video_driver.hpp"
|
#include "../../video/video_driver.hpp"
|
||||||
#include "../../scope.h"
|
#include "../../scope.h"
|
||||||
|
#include "../../walltime_func.h"
|
||||||
#include "macos.h"
|
#include "macos.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -415,27 +416,35 @@ public:
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
printf("Crash encountered, generating crash log...\n");
|
printf("Crash encountered, generating crash log...\n");
|
||||||
this->FillCrashLog(buffer, last);
|
|
||||||
printf("%s\n", buffer);
|
char *name_buffer_date = this->name_buffer + seprintf(this->name_buffer, lastof(this->name_buffer), "crash-");
|
||||||
printf("Crash log generated.\n\n");
|
UTCTime::Format(name_buffer_date, lastof(this->name_buffer), "%Y%m%dT%H%M%SZ");
|
||||||
|
|
||||||
printf("Writing crash log to disk...\n");
|
printf("Writing crash log to disk...\n");
|
||||||
if (!this->WriteCrashLog(buffer, filename_log, lastof(filename_log))) {
|
bool bret = this->WriteCrashLog("", this->filename_log, lastof(this->filename_log), this->name_buffer, &(this->crash_file));
|
||||||
filename_log[0] = '\0';
|
if (bret) {
|
||||||
|
printf("Crash log written to %s. Please add this file to any bug reports.\n\n", this->filename_log);
|
||||||
|
} else {
|
||||||
|
printf("Writing crash log failed. Please attach the output above to any bug reports.\n\n");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
this->crash_buffer_write = buffer;
|
||||||
|
|
||||||
|
this->FillCrashLog(buffer, last);
|
||||||
|
this->CloseCrashLogFile();
|
||||||
|
printf("Crash log generated.\n\n");
|
||||||
|
|
||||||
printf("Writing crash savegame...\n");
|
printf("Writing crash savegame...\n");
|
||||||
_savegame_DBGL_data = buffer;
|
_savegame_DBGL_data = buffer;
|
||||||
_save_DBGC_data = true;
|
_save_DBGC_data = true;
|
||||||
if (!this->WriteSavegame(filename_save, lastof(filename_save))) {
|
if (!this->WriteSavegame(filename_save, lastof(filename_save), this->name_buffer)) {
|
||||||
filename_save[0] = '\0';
|
filename_save[0] = '\0';
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Writing crash screenshot...\n");
|
printf("Writing crash screenshot...\n");
|
||||||
SetScreenshotAuxiliaryText("Crash Log", buffer);
|
SetScreenshotAuxiliaryText("Crash Log", buffer);
|
||||||
if (!this->WriteScreenshot(filename_screenshot, lastof(filename_screenshot))) {
|
if (!this->WriteScreenshot(filename_screenshot, lastof(filename_screenshot), this->name_buffer)) {
|
||||||
filename_screenshot[0] = '\0';
|
filename_screenshot[0] = '\0';
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
@@ -63,8 +63,7 @@ public:
|
|||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
#if defined(_MSC_VER) || defined(WITH_DBGHELP)
|
#if defined(_MSC_VER) || defined(WITH_DBGHELP)
|
||||||
char *AppendDecodedStacktrace(char *buffer, const char *last) const;
|
char *AppendDecodedStacktrace(char *buffer, const char *last) const;
|
||||||
#else
|
char *LogDebugExtra(char *buffer, const char *last) const override;
|
||||||
char *AppendDecodedStacktrace(char *buffer, const char *last) const { return buffer; }
|
|
||||||
#endif /* _MSC_VER || WITH_DBGHELP */
|
#endif /* _MSC_VER || WITH_DBGHELP */
|
||||||
|
|
||||||
|
|
||||||
@@ -159,6 +158,7 @@ static const char *GetAccessViolationTypeString(uint type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->CrashLogFaultSectionCheckpoint(buffer);
|
||||||
buffer += seprintf(buffer, last, " Message: %s\n\n",
|
buffer += seprintf(buffer, last, " Message: %s\n\n",
|
||||||
message == nullptr ? "<none>" : message);
|
message == nullptr ? "<none>" : message);
|
||||||
|
|
||||||
@@ -391,6 +391,8 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
this->CrashLogFaultSectionCheckpoint(buffer);
|
||||||
|
|
||||||
buffer += seprintf(buffer, last, "\n Bytes at instruction pointer:\n");
|
buffer += seprintf(buffer, last, "\n Bytes at instruction pointer:\n");
|
||||||
#ifdef _M_AMD64
|
#ifdef _M_AMD64
|
||||||
byte *b = (byte*)ep->ContextRecord->Rip;
|
byte *b = (byte*)ep->ContextRecord->Rip;
|
||||||
@@ -475,7 +477,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
|||||||
BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
|
BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
|
||||||
} proc;
|
} proc;
|
||||||
|
|
||||||
buffer += seprintf(buffer, last, "\nDecoded stack trace:\n");
|
buffer += seprintf(buffer, last, "Decoded stack trace:\n");
|
||||||
|
|
||||||
/* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */
|
/* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */
|
||||||
if (LoadLibraryList((Function*)&proc, dbg_import)) {
|
if (LoadLibraryList((Function*)&proc, dbg_import)) {
|
||||||
@@ -619,8 +621,16 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
|||||||
proc.pSymCleanup(hCur);
|
proc.pSymCleanup(hCur);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer + seprintf(buffer, last, "\n*** End of additional info ***\n");
|
return buffer + seprintf(buffer, last, "\n");;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log decoded stack trace
|
||||||
|
*/
|
||||||
|
char *CrashLogWindows::LogDebugExtra(char *buffer, const char *last) const
|
||||||
|
{
|
||||||
|
return this->AppendDecodedStacktrace(buffer, last);
|
||||||
|
}
|
||||||
#endif /* _MSC_VER || WITH_DBGHELP */
|
#endif /* _MSC_VER || WITH_DBGHELP */
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@@ -703,12 +713,15 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
|
|||||||
|
|
||||||
CrashLogWindows *log = new CrashLogWindows(ep);
|
CrashLogWindows *log = new CrashLogWindows(ep);
|
||||||
CrashLogWindows::current = log;
|
CrashLogWindows::current = log;
|
||||||
char *buf = log->FillCrashLog(log->crashlog, lastof(log->crashlog));
|
|
||||||
char *name_buffer_date = log->name_buffer + seprintf(log->name_buffer, lastof(log->name_buffer), "crash-");
|
char *name_buffer_date = log->name_buffer + seprintf(log->name_buffer, lastof(log->name_buffer), "crash-");
|
||||||
UTCTime::Format(name_buffer_date, lastof(log->name_buffer), "%Y%m%dT%H%M%SZ");
|
UTCTime::Format(name_buffer_date, lastof(log->name_buffer), "%Y%m%dT%H%M%SZ");
|
||||||
|
|
||||||
|
log->WriteCrashLog("", log->crashlog_filename, lastof(log->crashlog_filename), log->name_buffer, &(log->crash_file));
|
||||||
|
log->crash_buffer_write = log->crashlog;
|
||||||
|
log->FillCrashLog(log->crashlog, lastof(log->crashlog));
|
||||||
|
log->CloseCrashLogFile();
|
||||||
|
|
||||||
log->WriteCrashDump(log->crashdump_filename, lastof(log->crashdump_filename));
|
log->WriteCrashDump(log->crashdump_filename, lastof(log->crashdump_filename));
|
||||||
log->AppendDecodedStacktrace(buf, lastof(log->crashlog));
|
|
||||||
log->WriteCrashLog(log->crashlog, log->crashlog_filename, lastof(log->crashlog_filename), log->name_buffer);
|
|
||||||
SetScreenshotAuxiliaryText("Crash Log", log->crashlog);
|
SetScreenshotAuxiliaryText("Crash Log", log->crashlog);
|
||||||
log->WriteScreenshot(log->screenshot_filename, lastof(log->screenshot_filename), log->name_buffer);
|
log->WriteScreenshot(log->screenshot_filename, lastof(log->screenshot_filename), log->name_buffer);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user