Skip to content

Commit

Permalink
Color stacktraces printed by the crash handler when in a TTY
Browse files Browse the repository at this point in the history
This makes them easier to read.
  • Loading branch information
Calinou committed Feb 14, 2025
1 parent b607110 commit b76d3e3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
17 changes: 14 additions & 3 deletions platform/linuxbsd/crash_handler_linuxbsd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <link.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

static void handle_crash(int sig) {
signal(SIGSEGV, SIG_DFL);
Expand All @@ -72,9 +73,13 @@ static void handle_crash(int sig) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
}

// Dump the backtrace to stderr with a message to the user
// Dump the backtrace to stderr with a message to the user.
print_error("\n================================================================");
print_error(vformat("%s: Program crashed with signal %d", __FUNCTION__, sig));
if (isatty(fileno(stderr))) {
print_error(vformat("\x1b[1;91m%s: Program crashed with signal %d.\x1b[0m", __FUNCTION__, sig));
} else {
print_error(vformat("%s: Program crashed with signal %d.", __FUNCTION__, sig));
}

// Print the engine version just before, so that people are reminded to include the version in backtrace reports.
if (String(VERSION_HASH).is_empty()) {
Expand Down Expand Up @@ -133,7 +138,13 @@ static void handle_crash(int sig) {
}
}

print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i] : ""));
if (isatty(fileno(stderr))) {
// Print colors using ANSI escape codes for easier visual grepping.
print_error(vformat("\x1b[94m[%d] \x1b[96m%s \x1b[90m(%s)\x1b[0m", (int64_t)i, fname, err == OK ? addr2line_results[i] : ""));
} else {
// Not a TTY (could be writing to a file). Don't use ANSI escape codes.
print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i] : ""));
}
}

free(strings);
Expand Down
17 changes: 14 additions & 3 deletions platform/macos/crash_handler_macos.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#include <mach-o/dyld.h>
#include <mach-o/getsect.h>
Expand Down Expand Up @@ -96,9 +97,13 @@ static void handle_crash(int sig) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
}

// Dump the backtrace to stderr with a message to the user
// Dump the backtrace to stderr with a message to the user.
print_error("\n================================================================");
print_error(vformat("%s: Program crashed with signal %d", __FUNCTION__, sig));
if (isatty(fileno(stderr))) {
print_error(vformat("\x1b[1;91m%s: Program crashed with signal %d.\x1b[0m", __FUNCTION__, sig));
} else {
print_error(vformat("%s: Program crashed with signal %d.", __FUNCTION__, sig));
}

// Print the engine version just before, so that people are reminded to include the version in backtrace reports.
if (String(VERSION_HASH).is_empty()) {
Expand Down Expand Up @@ -165,7 +170,13 @@ static void handle_crash(int sig) {
}
}

print_error(vformat("[%d] %s", (int64_t)i, output));
if (isatty(fileno(stderr))) {
// Print colors using ANSI escape codes for easier visual grepping.
print_error(vformat("\x1b[94m[%d] \x1b[96m%s\x1b[0m", uint64_t(i), output.utf8().ptr()));
} else {
// Not a TTY (could be writing to a file). Don't use ANSI escape codes.
print_error(vformat("[%d] %s", uint64_t(i), output.utf8().ptr()));
}
}

free(strings);
Expand Down
8 changes: 4 additions & 4 deletions platform/windows/crash_handler_windows_seh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
}

print_error("\n================================================================");
print_error(vformat("%s: Program crashed", __FUNCTION__));
print_error(vformat("\x1b[1;91m%s: Program crashed.\x1b[0m", __FUNCTION__));

// Print the engine version just before, so that people are reminded to include the version in backtrace reports.
if (String(VERSION_HASH).is_empty()) {
Expand Down Expand Up @@ -204,12 +204,12 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
std::string fnName = symbol(process, frame.AddrPC.Offset).undecorated_name();

if (SymGetLineFromAddr64(process, frame.AddrPC.Offset, &offset_from_symbol, &line)) {
print_error(vformat("[%d] %s (%s:%d)", n, fnName.c_str(), (char *)line.FileName, (int)line.LineNumber));
print_error(vformat("\x1b[94m[%d] \x1b[96m%s \x1b[90m(%s:%d)\x1b[0m", n, fnName.c_str(), line.FileName, uint32_t(line.LineNumber)));
} else {
print_error(vformat("[%d] %s", n, fnName.c_str()));
print_error(vformat("\x1b[94m[%d] \x1b[96m%s\x1b[0m", n, fnName.c_str()));
}
} else {
print_error(vformat("[%d] ???", n));
print_error(vformat("\x1b[94m[%d] \x1b[96m???\x1b[0m", n));
}

n++;
Expand Down

0 comments on commit b76d3e3

Please sign in to comment.