Skip to content

Commit b76d3e3

Browse files
committed
Color stacktraces printed by the crash handler when in a TTY
This makes them easier to read.
1 parent b607110 commit b76d3e3

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

platform/linuxbsd/crash_handler_linuxbsd.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <link.h>
4848
#include <signal.h>
4949
#include <stdlib.h>
50+
#include <unistd.h>
5051

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

75-
// Dump the backtrace to stderr with a message to the user
76+
// Dump the backtrace to stderr with a message to the user.
7677
print_error("\n================================================================");
77-
print_error(vformat("%s: Program crashed with signal %d", __FUNCTION__, sig));
78+
if (isatty(fileno(stderr))) {
79+
print_error(vformat("\x1b[1;91m%s: Program crashed with signal %d.\x1b[0m", __FUNCTION__, sig));
80+
} else {
81+
print_error(vformat("%s: Program crashed with signal %d.", __FUNCTION__, sig));
82+
}
7883

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

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

139150
free(strings);

platform/macos/crash_handler_macos.mm

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <execinfo.h>
5050
#include <signal.h>
5151
#include <stdlib.h>
52+
#include <unistd.h>
5253

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

99-
// Dump the backtrace to stderr with a message to the user
100+
// Dump the backtrace to stderr with a message to the user.
100101
print_error("\n================================================================");
101-
print_error(vformat("%s: Program crashed with signal %d", __FUNCTION__, sig));
102+
if (isatty(fileno(stderr))) {
103+
print_error(vformat("\x1b[1;91m%s: Program crashed with signal %d.\x1b[0m", __FUNCTION__, sig));
104+
} else {
105+
print_error(vformat("%s: Program crashed with signal %d.", __FUNCTION__, sig));
106+
}
102107

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

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

171182
free(strings);

platform/windows/crash_handler_windows_seh.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
139139
}
140140

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

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

206206
if (SymGetLineFromAddr64(process, frame.AddrPC.Offset, &offset_from_symbol, &line)) {
207-
print_error(vformat("[%d] %s (%s:%d)", n, fnName.c_str(), (char *)line.FileName, (int)line.LineNumber));
207+
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)));
208208
} else {
209-
print_error(vformat("[%d] %s", n, fnName.c_str()));
209+
print_error(vformat("\x1b[94m[%d] \x1b[96m%s\x1b[0m", n, fnName.c_str()));
210210
}
211211
} else {
212-
print_error(vformat("[%d] ???", n));
212+
print_error(vformat("\x1b[94m[%d] \x1b[96m???\x1b[0m", n));
213213
}
214214

215215
n++;

0 commit comments

Comments
 (0)