Skip to content

Commit

Permalink
Engine stack trace on fatal errors
Browse files Browse the repository at this point in the history
  • Loading branch information
cvet committed Dec 27, 2024
1 parent f4fe427 commit 864ac80
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
47 changes: 43 additions & 4 deletions Source/Common/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ struct StackTraceData

static thread_local StackTraceData StackTrace;

static StackTraceData* CrashStackTrace;

extern void SetCrashStackTrace() noexcept // Called in backward.hpp
{
NO_STACK_TRACE_ENTRY();

CrashStackTrace = &StackTrace;
}

class BackwardOStreamBuffer : public std::streambuf
{
public:
Expand All @@ -103,10 +112,10 @@ class BackwardOStreamBuffer : public std::streambuf
return ch;
}

auto xsputn(const char_type* s, std::streamsize count) -> std::streamsize override
auto xsputn(const char_type* s, std::streamsize count) -> std::streamsize override /*noexcept*/
{
if (_firstCall) {
WriteLogFatalMessage("\nFATAL ERROR!\n\n");
WriteHeader();
_firstCall = false;
}

Expand All @@ -115,10 +124,39 @@ class BackwardOStreamBuffer : public std::streambuf
}

private:
void WriteHeader() const noexcept
{
WriteLogFatalMessage("\nFATAL ERROR!\n\n");

if (CrashStackTrace != nullptr) {
WriteLogFatalMessage("Stack trace (most recent call first):\n");

for (int i = std::min(static_cast<int>(CrashStackTrace->CallsCount), static_cast<int>(STACK_TRACE_MAX_SIZE)) - 1; i >= 0; i--) {
const auto& entry = CrashStackTrace->CallTree[i];
WriteLogFatalMessage("- ");
WriteLogFatalMessage(entry->function);
WriteLogFatalMessage(" (");
WriteLogFatalMessage(strex(entry->file).extractFileName());
WriteLogFatalMessage(" line ");
WriteLogFatalMessage(strex(strex::safe_format_tag {}, "{}", entry->line));
WriteLogFatalMessage(")\n");
}

if (CrashStackTrace->CallsCount > STACK_TRACE_MAX_SIZE) {
WriteLogFatalMessage("- ...and ");
WriteLogFatalMessage(strex(strex::safe_format_tag {}, "{}", CrashStackTrace->CallsCount - STACK_TRACE_MAX_SIZE));
WriteLogFatalMessage(" more entries\n");
}

WriteLogFatalMessage("\n");
}
}

bool _firstCall = true;
};

static BackwardOStreamBuffer BackwardOStreamBuf;
extern std::ostream BackwardOStream;
std::ostream BackwardOStream = std::ostream(&BackwardOStreamBuf); // Passed to Printer::print in backward.hpp

void CreateGlobalData()
Expand Down Expand Up @@ -147,12 +185,14 @@ static auto InsertCatchedMark(const string& st) -> string

// Skip 'Stack trace (most recent ...'
auto pos = catched_st.find('\n');

if (pos == string::npos) {
return st;
}

// Find stack traces intercection
pos = st.find(catched_st.substr(pos + 1));

if (pos == string::npos) {
return st;
}
Expand Down Expand Up @@ -305,8 +345,7 @@ auto GetStackTrace() -> string
}

if (st.CallsCount > STACK_TRACE_MAX_SIZE) {
ss << "- ..."
<< "and " << (st.CallsCount - STACK_TRACE_MAX_SIZE) << " more entries\n";
ss << "- ...and " << (st.CallsCount - STACK_TRACE_MAX_SIZE) << " more entries\n";
}

auto st_str = ss.str();
Expand Down
6 changes: 2 additions & 4 deletions Source/Common/StringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,13 +837,11 @@ auto strex::extractDir() -> strex&
return *this;
}

auto strex::extractFileName() -> strex&
auto strex::extractFileName() noexcept -> strex&
{
NO_STACK_TRACE_ENTRY();

formatPath();

const auto pos = _sv.find_last_of('/');
const auto pos = _sv.find_last_of("/\\");

if (pos != string::npos) {
_sv = _sv.substr(pos + 1);
Expand Down
3 changes: 1 addition & 2 deletions Source/Common/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,12 @@ class strex final

auto formatPath() -> strex&;
auto extractDir() -> strex&;
auto extractFileName() -> strex&;
auto extractFileName() noexcept -> strex&;
auto getFileExtension() -> strex&; // Extension without dot and lowered
auto eraseFileExtension() noexcept -> strex&; // Erase extension with dot
auto changeFileName(string_view new_name) -> strex&;
auto combinePath(string_view path) -> strex&;
auto normalizePathSlashes() -> strex&;

auto normalizeLineEndings() -> strex&;

#if FO_WINDOWS
Expand Down
2 changes: 2 additions & 0 deletions ThirdParty/backward-cpp/backward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4405,6 +4405,8 @@ class SignalHandling {
}

NOINLINE static void crash_handler(int skip, CONTEXT *ct = nullptr) {
extern void SetCrashStackTrace() noexcept; // (FOnline Patch)
SetCrashStackTrace(); // (FOnline Patch)

if (ct == nullptr) {
RtlCaptureContext(ctx());
Expand Down

0 comments on commit 864ac80

Please sign in to comment.