aboutsummaryrefslogtreecommitdiff
path: root/absl/debugging/failure_signal_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/debugging/failure_signal_handler.cc')
-rw-r--r--absl/debugging/failure_signal_handler.cc50
1 files changed, 33 insertions, 17 deletions
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index ef8ab9e5..570d1e50 100644
--- a/absl/debugging/failure_signal_handler.cc
+++ b/absl/debugging/failure_signal_handler.cc
@@ -31,6 +31,13 @@
#ifdef ABSL_HAVE_MMAP
#include <sys/mman.h>
+#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#endif
+
+#ifdef __linux__
+#include <sys/prctl.h>
#endif
#include <algorithm>
@@ -47,7 +54,7 @@
#include "absl/debugging/internal/examine_stack.h"
#include "absl/debugging/stacktrace.h"
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__wasi__)
#define ABSL_HAVE_SIGACTION
// Apple WatchOS and TVOS don't allow sigaltstack
// Apple macOS has sigaltstack, but using it makes backtrace() unusable.
@@ -77,10 +84,10 @@ struct FailureSignalData {
struct sigaction previous_action;
// StructSigaction is used to silence -Wmissing-field-initializers.
using StructSigaction = struct sigaction;
- #define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction()
+#define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction()
#else
void (*previous_handler)(int);
- #define FSD_PREVIOUS_INIT SIG_DFL
+#define FSD_PREVIOUS_INIT SIG_DFL
#endif
};
@@ -132,7 +139,7 @@ const char* FailureSignalToString(int signo) {
#ifdef ABSL_HAVE_SIGALTSTACK
static bool SetupAlternateStackOnce() {
-#if defined(__wasm__) || defined (__asjms__)
+#if defined(__wasm__) || defined(__asjms__)
const size_t page_mask = getpagesize() - 1;
#else
const size_t page_mask = static_cast<size_t>(sysconf(_SC_PAGESIZE)) - 1;
@@ -154,9 +161,6 @@ static bool SetupAlternateStackOnce() {
#ifndef MAP_STACK
#define MAP_STACK 0
#endif
-#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
sigstk.ss_sp = mmap(nullptr, sigstk.ss_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (sigstk.ss_sp == MAP_FAILED) {
@@ -172,6 +176,20 @@ static bool SetupAlternateStackOnce() {
if (sigaltstack(&sigstk, nullptr) != 0) {
ABSL_RAW_LOG(FATAL, "sigaltstack() failed with errno=%d", errno);
}
+
+#ifdef __linux__
+#if defined(PR_SET_VMA) && defined(PR_SET_VMA_ANON_NAME)
+ // Make a best-effort attempt to name the allocated region in
+ // /proc/$PID/smaps.
+ //
+ // The call to prctl() may fail if the kernel was not configured with the
+ // CONFIG_ANON_VMA_NAME kernel option. This is OK since the call is
+ // primarily a debugging aid.
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, sigstk.ss_sp, sigstk.ss_size,
+ "absl-signalstack");
+#endif
+#endif // __linux__
+
return true;
}
@@ -218,10 +236,6 @@ static void InstallOneFailureHandler(FailureSignalData* data,
#endif
-static void WriteToStderr(const char* data) {
- absl::raw_log_internal::AsyncSignalSafeWriteToStderr(data, strlen(data));
-}
-
static void WriteSignalMessage(int signo, int cpu,
void (*writerfn)(const char*)) {
char buf[96];
@@ -234,7 +248,7 @@ static void WriteSignalMessage(int signo, int cpu,
if (signal_string != nullptr && signal_string[0] != '\0') {
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%s ***\n",
@@ -297,7 +311,8 @@ static void PortableSleepForSeconds(int seconds) {
struct timespec sleep_time;
sleep_time.tv_sec = seconds;
sleep_time.tv_nsec = 0;
- while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {}
+ while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {
+ }
#endif
}
@@ -307,9 +322,7 @@ static void PortableSleepForSeconds(int seconds) {
// set amount of time. If AbslFailureSignalHandler() hangs for more than
// the alarm timeout, ImmediateAbortSignalHandler() will abort the
// program.
-static void ImmediateAbortSignalHandler(int) {
- RaiseToDefaultHandler(SIGABRT);
-}
+static void ImmediateAbortSignalHandler(int) { RaiseToDefaultHandler(SIGABRT); }
#endif
// absl::base_internal::GetTID() returns pid_t on most platforms, but
@@ -362,7 +375,10 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
#endif
// First write to stderr.
- WriteFailureInfo(signo, ucontext, my_cpu, WriteToStderr);
+ WriteFailureInfo(
+ signo, ucontext, my_cpu, +[](const char* data) {
+ absl::raw_log_internal::AsyncSignalSafeWriteError(data, strlen(data));
+ });
// Riskier code (because it is less likely to be async-signal-safe)
// goes after this point.