Go to the documentation of this file.
17 #include "absl/debugging/failure_signal_handler.h"
19 #include "absl/base/config.h"
29 #include <TargetConditionals.h>
44 #include "absl/base/attributes.h"
45 #include "absl/base/internal/raw_logging.h"
46 #include "absl/base/internal/sysinfo.h"
47 #include "absl/debugging/internal/examine_stack.h"
48 #include "absl/debugging/stacktrace.h"
51 #define ABSL_HAVE_SIGACTION
53 #if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \
54 !(defined(TARGET_OS_TV) && TARGET_OS_TV) && !defined(__QNX__)
55 #define ABSL_HAVE_SIGALTSTACK
74 #ifdef ABSL_HAVE_SIGACTION
78 #define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction()
80 void (*previous_handler)(
int);
81 #define FSD_PREVIOUS_INIT SIG_DFL
97 #undef FSD_PREVIOUS_INIT
102 if (
it.signo == signo) {
103 #ifdef ABSL_HAVE_SIGACTION
104 sigaction(signo, &
it.previous_action,
nullptr);
117 namespace debugging_internal {
121 if (
it.signo == signo) {
130 #ifdef ABSL_HAVE_SIGALTSTACK
133 #if defined(__wasm__) || defined (__asjms__)
134 const size_t page_mask = getpagesize() - 1;
136 const size_t page_mask = sysconf(_SC_PAGESIZE) - 1;
139 (std::max<size_t>(SIGSTKSZ, 65536) + page_mask) & ~page_mask;
140 #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
141 defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
147 memset(&sigstk, 0,
sizeof(sigstk));
148 sigstk.ss_size = stack_size;
150 #ifdef ABSL_HAVE_MMAP
154 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
155 #define MAP_ANONYMOUS MAP_ANON
157 sigstk.ss_sp = mmap(
nullptr, sigstk.ss_size, PROT_READ | PROT_WRITE,
158 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
159 if (sigstk.ss_sp == MAP_FAILED) {
163 sigstk.ss_sp = malloc(sigstk.ss_size);
164 if (sigstk.ss_sp ==
nullptr) {
169 if (sigaltstack(&sigstk,
nullptr) != 0) {
177 #ifdef ABSL_HAVE_SIGACTION
183 #ifdef ABSL_HAVE_SIGALTSTACK
192 void (*
handler)(
int, siginfo_t*,
void*)) {
193 struct sigaction act;
194 memset(&act, 0,
sizeof(act));
195 sigemptyset(&act.sa_mask);
196 act.sa_flags |= SA_SIGINFO;
199 act.sa_flags |= SA_NODEFER;
205 "sigaction() failed");
223 void (*writerfn)(
const char*)) {
225 char on_cpu[32] = {0};
227 snprintf(on_cpu,
sizeof(on_cpu),
" on cpu %d", cpu);
229 const char*
const signal_string =
231 if (signal_string !=
nullptr && signal_string[0] !=
'\0') {
232 snprintf(
buf,
sizeof(
buf),
"*** %s received at time=%ld%s ***\n",
234 static_cast<long>(time(
nullptr)),
237 snprintf(
buf,
sizeof(
buf),
"*** Signal %d received at time=%ld%s ***\n",
238 signo,
static_cast<long>(time(
nullptr)),
261 void* ucontext,
bool symbolize_stacktrace,
262 void (*writerfn)(
const char*,
void*),
void* writerfn_arg) {
263 constexpr
int kNumStackFrames = 32;
264 void*
stack[kNumStackFrames];
265 int frame_sizes[kNumStackFrames];
266 int min_dropped_frames;
268 stack, frame_sizes, kNumStackFrames,
270 ucontext, &min_dropped_frames);
273 depth, min_dropped_frames, symbolize_stacktrace, writerfn, writerfn_arg);
280 void (*writerfn)(
const char*)) {
294 struct timespec sleep_time;
296 sleep_time.tv_nsec = 0;
297 while (
nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {}
301 #ifdef ABSL_HAVE_ALARM
307 static void ImmediateAbortSignalHandler(
int) {
317 #ifndef ABSL_HAVE_SIGACTION
319 void* ucontext =
nullptr;
327 previous_failed_tid,
static_cast<intptr_t>(this_tid),
328 std::memory_order_acq_rel, std::memory_order_relaxed)) {
331 "Signal %d raised at PC=%p while already in AbslFailureSignalHandler()",
333 if (this_tid != previous_failed_tid) {
348 #ifdef ABSL_HAVE_SCHED_GETCPU
349 my_cpu = sched_getcpu();
352 #ifdef ABSL_HAVE_ALARM
356 signal(SIGALRM, ImmediateAbortSignalHandler);
#define ABSL_RAW_CHECK(condition, message)
std::chrono::duration< std::int_fast64_t > seconds
bool symbolize_stacktrace
void AsyncSignalSafeWriteToStderr(const char *s, size_t len)
return memset(p, 0, total)
static void WriteToStderr(const char *data)
void(* writerfn)(const char *)
#define ABSL_ATTRIBUTE_UNUSED
const char *const as_string
static void RaiseToPreviousHandler(int signo)
int nanosleep(const struct timespec *req, struct timespec *rem)
struct sigaction previous_action
int alarm_on_failure_secs
static void WriteFailureInfo(int signo, void *ucontext, int cpu, void(*writerfn)(const char *))
#define ABSL_NAMESPACE_END
#define ABSL_ATTRIBUTE_NOINLINE
static ABSL_ATTRIBUTE_NOINLINE void WriteStackTrace(void *ucontext, bool symbolize_stacktrace, void(*writerfn)(const char *, void *), void *writerfn_arg)
void * GetProgramCounter(void *const vuc)
bool call_previous_handler
static ABSL_CONST_INIT std::atomic< GetTidType > failed_tid(0)
struct sigaction StructSigaction
#define ABSL_NAMESPACE_BEGIN
static void InstallOneFailureHandler(FailureSignalData *data, void(*handler)(int, siginfo_t *, void *))
static void signal(notification *n)
static void WriterFnWrapper(const char *data, void *arg)
static void AbslFailureSignalHandler(int signo, siginfo_t *, void *ucontext)
void InstallFailureSignalHandler(const FailureSignalHandlerOptions &options)
static bool SetupAlternateStackOnce()
static void RaiseToDefaultHandler(int signo)
decltype(absl::base_internal::GetTID()) GetTidType
static const LogLevel ERROR
static void PortableSleepForSeconds(int seconds)
void(* writerfn)(const char *)
static void WriteSignalMessage(int signo, int cpu, void(*writerfn)(const char *))
#define FSD_PREVIOUS_INIT
void DumpPCAndFrameSizesAndStackTrace(void *const pc, void *const stack[], int frame_sizes[], int depth, int min_dropped_frames, bool symbolize_stacktrace, OutputWriter *writer, void *writer_arg)
static ABSL_CONST_INIT FailureSignalData failure_signal_data[]
ABSL_NAMESPACE_BEGIN static ABSL_CONST_INIT FailureSignalHandlerOptions fsh_options
#define ABSL_RAW_LOG(severity,...)
static int MaybeSetupAlternateStack()
const char * FailureSignalToString(int signo)
ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackFramesWithContext(void **result, int *sizes, int max_depth, int skip_count, const void *uc, int *min_dropped_frames)
grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:21