failure_signal_handler.cc 14 KB

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