summaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/failure_signal_handler.cc36
-rw-r--r--absl/debugging/failure_signal_handler_test.cc6
2 files changed, 32 insertions, 10 deletions
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index 5d13bdbb..a9ed6ef9 100644
--- a/absl/debugging/failure_signal_handler.cc
+++ b/absl/debugging/failure_signal_handler.cc
@@ -21,6 +21,7 @@
#ifdef _WIN32
#include <windows.h>
#else
+#include <sched.h>
#include <unistd.h>
#endif
@@ -219,17 +220,24 @@ static void WriteToStderr(const char* data) {
absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data));
}
-static void WriteSignalMessage(int signo, void (*writerfn)(const char*)) {
- char buf[64];
+static void WriteSignalMessage(int signo, int cpu,
+ void (*writerfn)(const char*)) {
+ char buf[96];
+ char on_cpu[32] = {0};
+ if (cpu != -1) {
+ snprintf(on_cpu, sizeof(on_cpu), " on cpu %d", cpu);
+ }
const char* const signal_string =
debugging_internal::FailureSignalToString(signo);
if (signal_string != nullptr && signal_string[0] != '\0') {
- snprintf(buf, sizeof(buf), "*** %s received at time=%ld ***\n",
+ snprintf(buf, sizeof(buf), "*** %s received at time=%ld%s ***\n",
signal_string,
- static_cast<long>(time(nullptr))); // NOLINT(runtime/int)
+ static_cast<long>(time(nullptr)), // NOLINT(runtime/int)
+ on_cpu);
} else {
- snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld ***\n",
- signo, static_cast<long>(time(nullptr))); // NOLINT(runtime/int)
+ snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld%s ***\n",
+ signo, static_cast<long>(time(nullptr)), // NOLINT(runtime/int)
+ on_cpu);
}
writerfn(buf);
}
@@ -269,10 +277,10 @@ ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace(
// Called by AbslFailureSignalHandler() to write the failure info. It is
// called once with writerfn set to WriteToStderr() and then possibly
// with writerfn set to the user provided function.
-static void WriteFailureInfo(int signo, void* ucontext,
+static void WriteFailureInfo(int signo, void* ucontext, int cpu,
void (*writerfn)(const char*)) {
WriterFnStruct writerfn_struct{writerfn};
- WriteSignalMessage(signo, writerfn);
+ WriteSignalMessage(signo, cpu, writerfn);
WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper,
&writerfn_struct);
}
@@ -334,6 +342,14 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
}
}
+ // Increase the chance that the CPU we report was the same CPU on which the
+ // signal was received by doing this as early as possible, i.e. after
+ // verifying that this is not a recursive signal handler invocation.
+ int my_cpu = -1;
+#ifdef ABSL_HAVE_SCHED_GETCPU
+ my_cpu = sched_getcpu();
+#endif
+
#ifdef ABSL_HAVE_ALARM
// Set an alarm to abort the program in case this code hangs or deadlocks.
if (fsh_options.alarm_on_failure_secs > 0) {
@@ -344,12 +360,12 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
#endif
// First write to stderr.
- WriteFailureInfo(signo, ucontext, WriteToStderr);
+ WriteFailureInfo(signo, ucontext, my_cpu, WriteToStderr);
// Riskier code (because it is less likely to be async-signal-safe)
// goes after this point.
if (fsh_options.writerfn != nullptr) {
- WriteFailureInfo(signo, ucontext, fsh_options.writerfn);
+ WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn);
}
if (fsh_options.call_previous_handler) {
diff --git a/absl/debugging/failure_signal_handler_test.cc b/absl/debugging/failure_signal_handler_test.cc
index d8283b2f..6a62428b 100644
--- a/absl/debugging/failure_signal_handler_test.cc
+++ b/absl/debugging/failure_signal_handler_test.cc
@@ -122,6 +122,12 @@ TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) {
"*** ", absl::debugging_internal::FailureSignalToString(signo),
" received at ")));
+ // On platforms where it is possible to get the current CPU, the
+ // CPU number is also logged. Check that it is present in output.
+#if defined(__linux__)
+ EXPECT_THAT(error_line, testing::HasSubstr(" on cpu "));
+#endif
+
if (absl::debugging_internal::StackTraceWorksForTest()) {
std::getline(error_output, error_line);
EXPECT_THAT(error_line, StartsWith("PC: "));