failure_signal_handler.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. //
  2. // Copyright 2018 The Abseil Authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // https://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #include "absl/debugging/failure_signal_handler.h"
  17. #include "absl/base/config.h"
  18. #ifdef _WIN32
  19. #include <windows.h>
  20. #else
  21. #include <sched.h>
  22. #include <unistd.h>
  23. #endif
  24. #ifdef __APPLE__
  25. #include <TargetConditionals.h>
  26. #endif
  27. #ifdef ABSL_HAVE_MMAP
  28. #include <sys/mman.h>
  29. #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
  30. #define MAP_ANONYMOUS MAP_ANON
  31. #endif
  32. #endif
  33. #ifdef __linux__
  34. #include <sys/prctl.h>
  35. #endif
  36. #include <algorithm>
  37. #include <atomic>
  38. #include <cerrno>
  39. #include <csignal>
  40. #include <cstdio>
  41. #include <cstring>
  42. #include <ctime>
  43. #include "absl/base/attributes.h"
  44. #include "absl/base/internal/raw_logging.h"
  45. #include "absl/base/internal/sysinfo.h"
  46. #include "absl/debugging/internal/examine_stack.h"
  47. #include "absl/debugging/stacktrace.h"
  48. #if !defined(_WIN32) && !defined(__wasi__)
  49. #define ABSL_HAVE_SIGACTION
  50. // Apple WatchOS and TVOS don't allow sigaltstack
  51. // Apple macOS has sigaltstack, but using it makes backtrace() unusable.
  52. #if !(defined(TARGET_OS_OSX) && TARGET_OS_OSX) && \
  53. !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \
  54. !(defined(TARGET_OS_TV) && TARGET_OS_TV) && !defined(__QNX__)
  55. #define ABSL_HAVE_SIGALTSTACK
  56. #endif
  57. #endif
  58. namespace absl {
  59. ABSL_NAMESPACE_BEGIN
  60. ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options;
  61. // Resets the signal handler for signo to the default action for that
  62. // signal, then raises the signal.
  63. static void RaiseToDefaultHandler(int signo) {
  64. signal(signo, SIG_DFL);
  65. raise(signo);
  66. }
  67. struct FailureSignalData {
  68. const int signo;
  69. const char* const as_string;
  70. #ifdef ABSL_HAVE_SIGACTION
  71. struct sigaction previous_action;
  72. // StructSigaction is used to silence -Wmissing-field-initializers.
  73. using StructSigaction = struct sigaction;
  74. #define FSD_PREVIOUS_INIT FailureSignalData::StructSigaction()
  75. #else
  76. void (*previous_handler)(int);
  77. #define FSD_PREVIOUS_INIT SIG_DFL
  78. #endif
  79. };
  80. ABSL_CONST_INIT static FailureSignalData failure_signal_data[] = {
  81. {SIGSEGV, "SIGSEGV", FSD_PREVIOUS_INIT},
  82. {SIGILL, "SIGILL", FSD_PREVIOUS_INIT},
  83. {SIGFPE, "SIGFPE", FSD_PREVIOUS_INIT},
  84. {SIGABRT, "SIGABRT", FSD_PREVIOUS_INIT},
  85. {SIGTERM, "SIGTERM", FSD_PREVIOUS_INIT},
  86. #ifndef _WIN32
  87. {SIGBUS, "SIGBUS", FSD_PREVIOUS_INIT},
  88. {SIGTRAP, "SIGTRAP", FSD_PREVIOUS_INIT},
  89. #endif
  90. };
  91. #undef FSD_PREVIOUS_INIT
  92. static void RaiseToPreviousHandler(int signo) {
  93. // Search for the previous handler.
  94. for (const auto& it : failure_signal_data) {
  95. if (it.signo == signo) {
  96. #ifdef ABSL_HAVE_SIGACTION
  97. sigaction(signo, &it.previous_action, nullptr);
  98. #else
  99. signal(signo, it.previous_handler);
  100. #endif
  101. raise(signo);
  102. return;
  103. }
  104. }
  105. // Not found, use the default handler.
  106. RaiseToDefaultHandler(signo);
  107. }
  108. namespace debugging_internal {
  109. const char* FailureSignalToString(int signo) {
  110. for (const auto& it : failure_signal_data) {
  111. if (it.signo == signo) {
  112. return it.as_string;
  113. }
  114. }
  115. return "";
  116. }
  117. } // namespace debugging_internal
  118. #ifdef ABSL_HAVE_SIGALTSTACK
  119. static bool SetupAlternateStackOnce() {
  120. #if defined(__wasm__) || defined(__asjms__)
  121. const size_t page_mask = getpagesize() - 1;
  122. #else
  123. const size_t page_mask = static_cast<size_t>(sysconf(_SC_PAGESIZE)) - 1;
  124. #endif
  125. size_t stack_size =
  126. (std::max(static_cast<size_t>(SIGSTKSZ), size_t{65536}) + page_mask) &
  127. ~page_mask;
  128. #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
  129. defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
  130. // Account for sanitizer instrumentation requiring additional stack space.
  131. stack_size *= 5;
  132. #endif
  133. stack_t sigstk;
  134. memset(&sigstk, 0, sizeof(sigstk));
  135. sigstk.ss_size = stack_size;
  136. #ifdef ABSL_HAVE_MMAP
  137. #ifndef MAP_STACK
  138. #define MAP_STACK 0
  139. #endif
  140. sigstk.ss_sp = mmap(nullptr, sigstk.ss_size, PROT_READ | PROT_WRITE,
  141. MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  142. if (sigstk.ss_sp == MAP_FAILED) {
  143. ABSL_RAW_LOG(FATAL, "mmap() for alternate signal stack failed");
  144. }
  145. #else
  146. sigstk.ss_sp = malloc(sigstk.ss_size);
  147. if (sigstk.ss_sp == nullptr) {
  148. ABSL_RAW_LOG(FATAL, "malloc() for alternate signal stack failed");
  149. }
  150. #endif
  151. if (sigaltstack(&sigstk, nullptr) != 0) {
  152. ABSL_RAW_LOG(FATAL, "sigaltstack() failed with errno=%d", errno);
  153. }
  154. #ifdef __linux__
  155. #if defined(PR_SET_VMA) && defined(PR_SET_VMA_ANON_NAME)
  156. // Make a best-effort attempt to name the allocated region in
  157. // /proc/$PID/smaps.
  158. //
  159. // The call to prctl() may fail if the kernel was not configured with the
  160. // CONFIG_ANON_VMA_NAME kernel option. This is OK since the call is
  161. // primarily a debugging aid.
  162. prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, sigstk.ss_sp, sigstk.ss_size,
  163. "absl-signalstack");
  164. #endif
  165. #endif // __linux__
  166. return true;
  167. }
  168. #endif
  169. #ifdef ABSL_HAVE_SIGACTION
  170. // Sets up an alternate stack for signal handlers once.
  171. // Returns the appropriate flag for sig_action.sa_flags
  172. // if the system supports using an alternate stack.
  173. static int MaybeSetupAlternateStack() {
  174. #ifdef ABSL_HAVE_SIGALTSTACK
  175. ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce();
  176. return SA_ONSTACK;
  177. #else
  178. return 0;
  179. #endif
  180. }
  181. static void InstallOneFailureHandler(FailureSignalData* data,
  182. void (*handler)(int, siginfo_t*, void*)) {
  183. struct sigaction act;
  184. memset(&act, 0, sizeof(act));
  185. sigemptyset(&act.sa_mask);
  186. act.sa_flags |= SA_SIGINFO;
  187. // SA_NODEFER is required to handle SIGABRT from
  188. // ImmediateAbortSignalHandler().
  189. act.sa_flags |= SA_NODEFER;
  190. if (fsh_options.use_alternate_stack) {
  191. act.sa_flags |= MaybeSetupAlternateStack();
  192. }
  193. act.sa_sigaction = handler;
  194. ABSL_RAW_CHECK(sigaction(data->signo, &act, &data->previous_action) == 0,
  195. "sigaction() failed");
  196. }
  197. #else
  198. static void InstallOneFailureHandler(FailureSignalData* data,
  199. void (*handler)(int)) {
  200. data->previous_handler = signal(data->signo, handler);
  201. ABSL_RAW_CHECK(data->previous_handler != SIG_ERR, "signal() failed");
  202. }
  203. #endif
  204. static void WriteSignalMessage(int signo, int cpu,
  205. void (*writerfn)(const char*)) {
  206. char buf[96];
  207. char on_cpu[32] = {0};
  208. if (cpu != -1) {
  209. snprintf(on_cpu, sizeof(on_cpu), " on cpu %d", cpu);
  210. }
  211. const char* const signal_string =
  212. debugging_internal::FailureSignalToString(signo);
  213. if (signal_string != nullptr && signal_string[0] != '\0') {
  214. snprintf(buf, sizeof(buf), "*** %s received at time=%ld%s ***\n",
  215. signal_string,
  216. static_cast<long>(time(nullptr)), // NOLINT(runtime/int)
  217. on_cpu);
  218. } else {
  219. snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld%s ***\n",
  220. signo, static_cast<long>(time(nullptr)), // NOLINT(runtime/int)
  221. on_cpu);
  222. }
  223. writerfn(buf);
  224. }
  225. // `void*` might not be big enough to store `void(*)(const char*)`.
  226. struct WriterFnStruct {
  227. void (*writerfn)(const char*);
  228. };
  229. // Many of the absl::debugging_internal::Dump* functions in
  230. // examine_stack.h take a writer function pointer that has a void* arg
  231. // for historical reasons. failure_signal_handler_writer only takes a
  232. // data pointer. This function converts between these types.
  233. static void WriterFnWrapper(const char* data, void* arg) {
  234. static_cast<WriterFnStruct*>(arg)->writerfn(data);
  235. }
  236. // Convenient wrapper around DumpPCAndFrameSizesAndStackTrace() for signal
  237. // handlers. "noinline" so that GetStackFrames() skips the top-most stack
  238. // frame for this function.
  239. ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace(
  240. void* ucontext, bool symbolize_stacktrace,
  241. void (*writerfn)(const char*, void*), void* writerfn_arg) {
  242. constexpr int kNumStackFrames = 32;
  243. void* stack[kNumStackFrames];
  244. int frame_sizes[kNumStackFrames];
  245. int min_dropped_frames;
  246. int depth = absl::GetStackFramesWithContext(
  247. stack, frame_sizes, kNumStackFrames,
  248. 1, // Do not include this function in stack trace.
  249. ucontext, &min_dropped_frames);
  250. absl::debugging_internal::DumpPCAndFrameSizesAndStackTrace(
  251. absl::debugging_internal::GetProgramCounter(ucontext), stack, frame_sizes,
  252. depth, min_dropped_frames, symbolize_stacktrace, writerfn, writerfn_arg);
  253. }
  254. // Called by AbslFailureSignalHandler() to write the failure info. It is
  255. // called once with writerfn set to WriteToStderr() and then possibly
  256. // with writerfn set to the user provided function.
  257. static void WriteFailureInfo(int signo, void* ucontext, int cpu,
  258. void (*writerfn)(const char*)) {
  259. WriterFnStruct writerfn_struct{writerfn};
  260. WriteSignalMessage(signo, cpu, writerfn);
  261. WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper,
  262. &writerfn_struct);
  263. }
  264. // absl::SleepFor() can't be used here since AbslInternalSleepFor()
  265. // may be overridden to do something that isn't async-signal-safe on
  266. // some platforms.
  267. static void PortableSleepForSeconds(int seconds) {
  268. #ifdef _WIN32
  269. Sleep(static_cast<DWORD>(seconds * 1000));
  270. #else
  271. struct timespec sleep_time;
  272. sleep_time.tv_sec = seconds;
  273. sleep_time.tv_nsec = 0;
  274. while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {
  275. }
  276. #endif
  277. }
  278. #ifdef ABSL_HAVE_ALARM
  279. // AbslFailureSignalHandler() installs this as a signal handler for
  280. // SIGALRM, then sets an alarm to be delivered to the program after a
  281. // set amount of time. If AbslFailureSignalHandler() hangs for more than
  282. // the alarm timeout, ImmediateAbortSignalHandler() will abort the
  283. // program.
  284. static void ImmediateAbortSignalHandler(int) { RaiseToDefaultHandler(SIGABRT); }
  285. #endif
  286. // absl::base_internal::GetTID() returns pid_t on most platforms, but
  287. // returns absl::base_internal::pid_t on Windows.
  288. using GetTidType = decltype(absl::base_internal::GetTID());
  289. ABSL_CONST_INIT static std::atomic<GetTidType> failed_tid(0);
  290. #ifndef ABSL_HAVE_SIGACTION
  291. static void AbslFailureSignalHandler(int signo) {
  292. void* ucontext = nullptr;
  293. #else
  294. static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
  295. #endif
  296. const GetTidType this_tid = absl::base_internal::GetTID();
  297. GetTidType previous_failed_tid = 0;
  298. if (!failed_tid.compare_exchange_strong(previous_failed_tid, this_tid,
  299. std::memory_order_acq_rel,
  300. std::memory_order_relaxed)) {
  301. ABSL_RAW_LOG(
  302. ERROR,
  303. "Signal %d raised at PC=%p while already in AbslFailureSignalHandler()",
  304. signo, absl::debugging_internal::GetProgramCounter(ucontext));
  305. if (this_tid != previous_failed_tid) {
  306. // Another thread is already in AbslFailureSignalHandler(), so wait
  307. // a bit for it to finish. If the other thread doesn't kill us,
  308. // we do so after sleeping.
  309. PortableSleepForSeconds(3);
  310. RaiseToDefaultHandler(signo);
  311. // The recursively raised signal may be blocked until we return.
  312. return;
  313. }
  314. }
  315. // Increase the chance that the CPU we report was the same CPU on which the
  316. // signal was received by doing this as early as possible, i.e. after
  317. // verifying that this is not a recursive signal handler invocation.
  318. int my_cpu = -1;
  319. #ifdef ABSL_HAVE_SCHED_GETCPU
  320. my_cpu = sched_getcpu();
  321. #endif
  322. #ifdef ABSL_HAVE_ALARM
  323. // Set an alarm to abort the program in case this code hangs or deadlocks.
  324. if (fsh_options.alarm_on_failure_secs > 0) {
  325. alarm(0); // Cancel any existing alarms.
  326. signal(SIGALRM, ImmediateAbortSignalHandler);
  327. alarm(static_cast<unsigned int>(fsh_options.alarm_on_failure_secs));
  328. }
  329. #endif
  330. // First write to stderr.
  331. WriteFailureInfo(
  332. signo, ucontext, my_cpu, +[](const char* data) {
  333. absl::raw_log_internal::AsyncSignalSafeWriteError(data, strlen(data));
  334. });
  335. // Riskier code (because it is less likely to be async-signal-safe)
  336. // goes after this point.
  337. if (fsh_options.writerfn != nullptr) {
  338. WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn);
  339. fsh_options.writerfn(nullptr);
  340. }
  341. if (fsh_options.call_previous_handler) {
  342. RaiseToPreviousHandler(signo);
  343. } else {
  344. RaiseToDefaultHandler(signo);
  345. }
  346. }
  347. void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) {
  348. fsh_options = options;
  349. for (auto& it : failure_signal_data) {
  350. InstallOneFailureHandler(&it, AbslFailureSignalHandler);
  351. }
  352. }
  353. ABSL_NAMESPACE_END
  354. } // namespace absl