46 #define ABSL_HAVE_SIGACTION 56 signal(signo, SIG_DFL);
63 #ifdef ABSL_HAVE_SIGACTION 67 #define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction() 69 void (*previous_handler)(int);
70 #define FSD_PREVIOUS_INIT SIG_DFL 76 {SIGILL,
"SIGILL", FSD_PREVIOUS_INIT},
77 {SIGFPE,
"SIGFPE", FSD_PREVIOUS_INIT},
78 {SIGABRT,
"SIGABRT", FSD_PREVIOUS_INIT},
79 {SIGTERM,
"SIGTERM", FSD_PREVIOUS_INIT},
81 {SIGBUS,
"SIGBUS", FSD_PREVIOUS_INIT},
82 {SIGTRAP,
"SIGTRAP", FSD_PREVIOUS_INIT},
86 #undef FSD_PREVIOUS_INIT 90 for (
const auto& it : failure_signal_data) {
91 if (it.signo == signo) {
92 #ifdef ABSL_HAVE_SIGACTION 93 sigaction(signo, &it.previous_action,
nullptr);
95 signal(signo, it.previous_handler);
106 namespace debugging_internal {
109 for (
const auto& it : failure_signal_data) {
110 if (it.signo == signo) {
122 #if defined(__wasm__) || defined (__asjms__) 123 const size_t page_mask = getpagesize() - 1;
125 const size_t page_mask = sysconf(_SC_PAGESIZE) - 1;
127 size_t stack_size = (std::max(SIGSTKSZ, 65536) + page_mask) & ~page_mask;
128 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ 129 defined(THREAD_SANITIZER) 135 memset(&sigstk, 0,
sizeof(sigstk));
136 sigstk.ss_size = stack_size;
138 #ifdef ABSL_HAVE_MMAP 142 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) 143 #define MAP_ANONYMOUS MAP_ANON 145 sigstk.ss_sp = mmap(
nullptr, sigstk.ss_size, PROT_READ | PROT_WRITE,
146 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
147 if (sigstk.ss_sp == MAP_FAILED) {
148 ABSL_RAW_LOG(FATAL,
"mmap() for alternate signal stack failed");
151 sigstk.ss_sp = malloc(sigstk.ss_size);
152 if (sigstk.ss_sp ==
nullptr) {
153 ABSL_RAW_LOG(FATAL,
"malloc() for alternate signal stack failed");
157 if (sigaltstack(&sigstk,
nullptr) != 0) {
158 ABSL_RAW_LOG(FATAL,
"sigaltstack() failed with errno=%d", errno);
165 #ifdef ABSL_HAVE_SIGACTION 180 void (*handler)(
int, siginfo_t*,
void*)) {
181 struct sigaction act;
182 memset(&act, 0,
sizeof(act));
183 sigemptyset(&act.sa_mask);
184 act.sa_flags |= SA_SIGINFO;
187 act.sa_flags |= SA_NODEFER;
188 if (fsh_options.use_alternate_stack) {
191 act.sa_sigaction = handler;
193 "sigaction() failed");
199 void (*handler)(
int)) {
200 data->previous_handler = signal(data->
signo, handler);
201 ABSL_RAW_CHECK(data->previous_handler != SIG_ERR,
"signal() failed");
207 int old_errno = errno;
214 const char*
const signal_string =
216 if (signal_string !=
nullptr && signal_string[0] !=
'\0') {
217 snprintf(buf,
sizeof(buf),
"*** %s received at time=%ld ***\n",
219 static_cast<long>(time(
nullptr)));
221 snprintf(buf,
sizeof(buf),
"*** Signal %d received at time=%ld ***\n",
222 signo, static_cast<long>(time(
nullptr)));
229 void (*writerfn)(
const char*);
244 void* ucontext,
bool symbolize_stacktrace,
245 void (*writerfn)(
const char*,
void*),
void* writerfn_arg) {
246 constexpr
int kNumStackFrames = 32;
247 void*
stack[kNumStackFrames];
248 int frame_sizes[kNumStackFrames];
249 int min_dropped_frames;
251 stack, frame_sizes, kNumStackFrames,
253 ucontext, &min_dropped_frames);
256 depth, min_dropped_frames, symbolize_stacktrace, writerfn, writerfn_arg);
263 void (*writerfn)(
const char*)) {
275 Sleep(seconds * 1000);
277 struct timespec sleep_time;
279 sleep_time.tv_nsec = 0;
280 while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {}
284 #ifdef ABSL_HAVE_ALARM 290 static void ImmediateAbortSignalHandler(
int) {
300 #ifndef ABSL_HAVE_SIGACTION 302 void* ucontext =
nullptr;
310 previous_failed_tid, static_cast<intptr_t>(this_tid),
311 std::memory_order_acq_rel, std::memory_order_relaxed)) {
314 "Signal %d raised at PC=%p while already in AbslFailureSignalHandler()",
316 if (this_tid != previous_failed_tid) {
327 #ifdef ABSL_HAVE_ALARM 329 if (fsh_options.alarm_on_failure_secs > 0) {
331 signal(SIGALRM, ImmediateAbortSignalHandler);
332 alarm(fsh_options.alarm_on_failure_secs);
341 if (fsh_options.writerfn !=
nullptr) {
345 if (fsh_options.call_previous_handler) {
353 fsh_options = options;
354 for (
auto& it : failure_signal_data) {
void SafeWriteToStderr(const char *s, size_t len)
#define ABSL_ATTRIBUTE_UNUSED
const char *const as_string
struct sigaction previous_action
const char * FailureSignalToString(int signo)
static void WriteFailureInfo(int signo, void *ucontext, void(*writerfn)(const char *))
static ABSL_CONST_INIT std::atomic< GetTidType > failed_tid(0)
struct sigaction StructSigaction
#define ABSL_RAW_LOG(severity,...)
static ABSL_ATTRIBUTE_NOINLINE void WriteStackTrace(void *ucontext, bool symbolize_stacktrace, void(*writerfn)(const char *, void *), void *writerfn_arg)
static void RaiseToPreviousHandler(int signo)
static void AbslFailureSignalHandler(int signo, siginfo_t *, void *ucontext)
#define FSD_PREVIOUS_INIT
std::chrono::duration< std::int_fast64_t > seconds
static void WriterFnWrapper(const char *data, void *arg)
static void InstallOneFailureHandler(FailureSignalData *data, void(*handler)(int, siginfo_t *, void *))
#define ABSL_RAW_CHECK(condition, message)
static bool SetupAlternateStackOnce()
decltype(absl::base_internal::GetTID()) GetTidType
static ABSL_CONST_INIT FailureSignalHandlerOptions fsh_options
static char data[kDataSize]
static void RaiseToDefaultHandler(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)
static void PortableSleepForSeconds(int seconds)
#define ABSL_ATTRIBUTE_NOINLINE
void InstallFailureSignalHandler(const FailureSignalHandlerOptions &options)
void DumpPCAndFrameSizesAndStackTrace(void *pc, void *const stack[], int frame_sizes[], int depth, int min_dropped_frames, bool symbolize_stacktrace, void(*writerfn)(const char *, void *), void *writerfn_arg)
void * GetProgramCounter(void *vuc)
static void WriteSignalMessage(int signo, void(*writerfn)(const char *))
static ABSL_CONST_INIT FailureSignalData failure_signal_data[]
static int MaybeSetupAlternateStack()
static void WriteToStderr(const char *data)