diff options
Diffstat (limited to 'absl/debugging/failure_signal_handler.cc')
-rw-r--r-- | absl/debugging/failure_signal_handler.cc | 50 |
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. |