fall back to .debug_info scan in fatal signal handler
[folly.git] / folly / experimental / symbolizer / SignalHandler.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
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  *   http://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
17 // This is heavily inspired by the signal handler from google-glog
18
19 #include <folly/experimental/symbolizer/SignalHandler.h>
20
21 #include <pthread.h>
22 #include <signal.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include <algorithm>
27 #include <atomic>
28 #include <ctime>
29 #include <mutex>
30 #include <vector>
31
32 #include <glog/logging.h>
33
34 #include <folly/Conv.h>
35 #include <folly/FileUtil.h>
36 #include <folly/Portability.h>
37 #include <folly/ScopeGuard.h>
38 #include <folly/experimental/symbolizer/ElfCache.h>
39 #include <folly/experimental/symbolizer/Symbolizer.h>
40 #include <folly/portability/SysSyscall.h>
41
42 namespace folly { namespace symbolizer {
43
44 namespace {
45
46 /**
47  * Fatal signal handler registry.
48  */
49 class FatalSignalCallbackRegistry {
50  public:
51   FatalSignalCallbackRegistry();
52
53   void add(SignalCallback func);
54   void markInstalled();
55   void run();
56
57  private:
58   std::atomic<bool> installed_;
59   std::mutex mutex_;
60   std::vector<SignalCallback> handlers_;
61 };
62
63 FatalSignalCallbackRegistry::FatalSignalCallbackRegistry()
64   : installed_(false) {
65 }
66
67 void FatalSignalCallbackRegistry::add(SignalCallback func) {
68   std::lock_guard<std::mutex> lock(mutex_);
69   CHECK(!installed_)
70     << "FatalSignalCallbackRegistry::add may not be used "
71        "after installing the signal handlers.";
72   handlers_.push_back(func);
73 }
74
75 void FatalSignalCallbackRegistry::markInstalled() {
76   std::lock_guard<std::mutex> lock(mutex_);
77   CHECK(!installed_.exchange(true))
78     << "FatalSignalCallbackRegistry::markInstalled must be called "
79     << "at most once";
80 }
81
82 void FatalSignalCallbackRegistry::run() {
83   if (!installed_) {
84     return;
85   }
86
87   for (auto& fn : handlers_) {
88     fn();
89   }
90 }
91
92 // Leak it so we don't have to worry about destruction order
93 FatalSignalCallbackRegistry* gFatalSignalCallbackRegistry =
94   new FatalSignalCallbackRegistry;
95
96 struct {
97   int number;
98   const char* name;
99   struct sigaction oldAction;
100 } kFatalSignals[] = {
101   { SIGSEGV, "SIGSEGV", {} },
102   { SIGILL,  "SIGILL",  {} },
103   { SIGFPE,  "SIGFPE",  {} },
104   { SIGABRT, "SIGABRT", {} },
105   { SIGBUS,  "SIGBUS",  {} },
106   { SIGTERM, "SIGTERM", {} },
107   { 0,       nullptr,   {} }
108 };
109
110 void callPreviousSignalHandler(int signum) {
111   // Restore disposition to old disposition, then kill ourselves with the same
112   // signal. The signal will be blocked until we return from our handler,
113   // then it will invoke the default handler and abort.
114   for (auto p = kFatalSignals; p->name; ++p) {
115     if (p->number == signum) {
116       sigaction(signum, &p->oldAction, nullptr);
117       raise(signum);
118       return;
119     }
120   }
121
122   // Not one of the signals we know about. Oh well. Reset to default.
123   struct sigaction sa;
124   memset(&sa, 0, sizeof(sa));
125   sa.sa_handler = SIG_DFL;
126   sigaction(signum, &sa, nullptr);
127   raise(signum);
128 }
129
130 // Note: not thread-safe, but that's okay, as we only let one thread
131 // in our signal handler at a time.
132 //
133 // Leak it so we don't have to worry about destruction order
134 constexpr size_t kMinSignalSafeElfCacheSize = 500;
135 auto gSignalSafeElfCache = new SignalSafeElfCache(
136     std::max(countLoadedElfFiles(), kMinSignalSafeElfCacheSize));
137
138 // Buffered writer (using a fixed-size buffer). We try to write only once
139 // to prevent interleaving with messages written from other threads.
140 //
141 // Leak it so we don't have to worry about destruction order.
142 auto gPrinter = new FDSymbolizePrinter(STDERR_FILENO,
143                                        SymbolizePrinter::COLOR_IF_TTY,
144                                        size_t(64) << 10);  // 64KiB
145
146 // Flush gPrinter, also fsync, in case we're about to crash again...
147 void flush() {
148   gPrinter->flush();
149   fsyncNoInt(STDERR_FILENO);
150 }
151
152 void printDec(uint64_t val) {
153   char buf[20];
154   uint32_t n = uint64ToBufferUnsafe(val, buf);
155   gPrinter->print(StringPiece(buf, n));
156 }
157
158 const char kHexChars[] = "0123456789abcdef";
159 void printHex(uint64_t val) {
160   // TODO(tudorb): Add this to folly/Conv.h
161   char buf[2 + 2 * sizeof(uint64_t)];  // "0x" prefix, 2 digits for each byte
162
163   char* end = buf + sizeof(buf);
164   char* p = end;
165   do {
166     *--p = kHexChars[val & 0x0f];
167     val >>= 4;
168   } while (val != 0);
169   *--p = 'x';
170   *--p = '0';
171
172   gPrinter->print(StringPiece(p, end));
173 }
174
175 void print(StringPiece sp) {
176   gPrinter->print(sp);
177 }
178
179 void dumpTimeInfo() {
180   SCOPE_EXIT { flush(); };
181   time_t now = time(nullptr);
182   print("*** Aborted at ");
183   printDec(now);
184   print(" (Unix time, try 'date -d @");
185   printDec(now);
186   print("') ***\n");
187 }
188
189 const char* sigill_reason(int si_code) {
190   switch (si_code) {
191     case ILL_ILLOPC:
192       return "illegal opcode";
193     case ILL_ILLOPN:
194       return "illegal operand";
195     case ILL_ILLADR:
196       return "illegal addressing mode";
197     case ILL_ILLTRP:
198       return "illegal trap";
199     case ILL_PRVOPC:
200       return "privileged opcode";
201     case ILL_PRVREG:
202       return "privileged register";
203     case ILL_COPROC:
204       return "coprocessor error";
205     case ILL_BADSTK:
206       return "internal stack error";
207
208     default:
209       return nullptr;
210   }
211 }
212
213 const char* sigfpe_reason(int si_code) {
214   switch (si_code) {
215     case FPE_INTDIV:
216       return "integer divide by zero";
217     case FPE_INTOVF:
218       return "integer overflow";
219     case FPE_FLTDIV:
220       return "floating-point divide by zero";
221     case FPE_FLTOVF:
222       return "floating-point overflow";
223     case FPE_FLTUND:
224       return "floating-point underflow";
225     case FPE_FLTRES:
226       return "floating-point inexact result";
227     case FPE_FLTINV:
228       return "floating-point invalid operation";
229     case FPE_FLTSUB:
230       return "subscript out of range";
231
232     default:
233       return nullptr;
234   }
235 }
236
237 const char* sigsegv_reason(int si_code) {
238   switch (si_code) {
239     case SEGV_MAPERR:
240       return "address not mapped to object";
241     case SEGV_ACCERR:
242       return "invalid permissions for mapped object";
243
244     default:
245       return nullptr;
246   }
247 }
248
249 const char* sigbus_reason(int si_code) {
250   switch (si_code) {
251     case BUS_ADRALN:
252       return "invalid address alignment";
253     case BUS_ADRERR:
254       return "nonexistent physical address";
255     case BUS_OBJERR:
256       return "object-specific hardware error";
257
258     // MCEERR_AR and MCEERR_AO: in sigaction(2) but not in headers.
259
260     default:
261       return nullptr;
262   }
263 }
264
265 const char* sigtrap_reason(int si_code) {
266   switch (si_code) {
267     case TRAP_BRKPT:
268       return "process breakpoint";
269     case TRAP_TRACE:
270       return "process trace trap";
271
272     // TRAP_BRANCH and TRAP_HWBKPT: in sigaction(2) but not in headers.
273
274     default:
275       return nullptr;
276   }
277 }
278
279 const char* sigchld_reason(int si_code) {
280   switch (si_code) {
281     case CLD_EXITED:
282       return "child has exited";
283     case CLD_KILLED:
284       return "child was killed";
285     case CLD_DUMPED:
286       return "child terminated abnormally";
287     case CLD_TRAPPED:
288       return "traced child has trapped";
289     case CLD_STOPPED:
290       return "child has stopped";
291     case CLD_CONTINUED:
292       return "stopped child has continued";
293
294     default:
295       return nullptr;
296   }
297 }
298
299 const char* sigio_reason(int si_code) {
300   switch (si_code) {
301     case POLL_IN:
302       return "data input available";
303     case POLL_OUT:
304       return "output buffers available";
305     case POLL_MSG:
306       return "input message available";
307     case POLL_ERR:
308       return "I/O error";
309     case POLL_PRI:
310       return "high priority input available";
311     case POLL_HUP:
312       return "device disconnected";
313
314     default:
315       return nullptr;
316   }
317 }
318
319 const char* signal_reason(int signum, int si_code) {
320   switch (signum) {
321     case SIGILL:
322       return sigill_reason(si_code);
323     case SIGFPE:
324       return sigfpe_reason(si_code);
325     case SIGSEGV:
326       return sigsegv_reason(si_code);
327     case SIGBUS:
328       return sigbus_reason(si_code);
329     case SIGTRAP:
330       return sigtrap_reason(si_code);
331     case SIGCHLD:
332       return sigchld_reason(si_code);
333     case SIGIO:
334       return sigio_reason(si_code); // aka SIGPOLL
335
336     default:
337       return nullptr;
338   }
339 }
340
341 void dumpSignalInfo(int signum, siginfo_t* siginfo) {
342   SCOPE_EXIT { flush(); };
343   // Get the signal name, if possible.
344   const char* name = nullptr;
345   for (auto p = kFatalSignals; p->name; ++p) {
346     if (p->number == signum) {
347       name = p->name;
348       break;
349     }
350   }
351
352   print("*** Signal ");
353   printDec(signum);
354   if (name) {
355     print(" (");
356     print(name);
357     print(")");
358   }
359
360   print(" (");
361   printHex(reinterpret_cast<uint64_t>(siginfo->si_addr));
362   print(") received by PID ");
363   printDec(getpid());
364   print(" (pthread TID ");
365   printHex((uint64_t)pthread_self());
366   print(") (linux TID ");
367   printDec(syscall(__NR_gettid));
368
369   // Kernel-sourced signals don't give us useful info for pid/uid.
370   if (siginfo->si_code != SI_KERNEL) {
371     print(") (maybe from PID ");
372     printDec(siginfo->si_pid);
373     print(", UID ");
374     printDec(siginfo->si_uid);
375   }
376
377   auto reason = signal_reason(signum, siginfo->si_code);
378
379   if (reason != nullptr) {
380     print(") (code: ");
381     print(reason);
382   }
383
384   print("), stack trace: ***\n");
385 }
386
387 FOLLY_NOINLINE void dumpStackTrace(bool symbolize);
388
389 void dumpStackTrace(bool symbolize) {
390   SCOPE_EXIT { flush(); };
391   // Get and symbolize stack trace
392   constexpr size_t kMaxStackTraceDepth = 100;
393   FrameArray<kMaxStackTraceDepth> addresses;
394
395   // Skip the getStackTrace frame
396   if (!getStackTraceSafe(addresses)) {
397     print("(error retrieving stack trace)\n");
398   } else if (symbolize) {
399     // Do our best to populate location info, process is going to terminate,
400     // so performance isn't critical.
401     Symbolizer symbolizer(gSignalSafeElfCache, Dwarf::LocationInfoMode::FULL);
402     symbolizer.symbolize(addresses);
403
404     // Skip the top 2 frames:
405     // getStackTraceSafe
406     // dumpStackTrace (here)
407     //
408     // Leaving signalHandler on the stack for clarity, I think.
409     gPrinter->println(addresses, 2);
410   } else {
411     print("(safe mode, symbolizer not available)\n");
412     AddressFormatter formatter;
413     for (size_t i = 0; i < addresses.frameCount; ++i) {
414       print(formatter.format(addresses.addresses[i]));
415       print("\n");
416     }
417   }
418 }
419
420 // On Linux, pthread_t is a pointer, so 0 is an invalid value, which we
421 // take to indicate "no thread in the signal handler".
422 //
423 // POSIX defines PTHREAD_NULL for this purpose, but that's not available.
424 constexpr pthread_t kInvalidThreadId = 0;
425
426 std::atomic<pthread_t> gSignalThread(kInvalidThreadId);
427 std::atomic<bool> gInRecursiveSignalHandler(false);
428
429 // Here be dragons.
430 void innerSignalHandler(int signum, siginfo_t* info, void* /* uctx */) {
431   // First, let's only let one thread in here at a time.
432   pthread_t myId = pthread_self();
433
434   pthread_t prevSignalThread = kInvalidThreadId;
435   while (!gSignalThread.compare_exchange_strong(prevSignalThread, myId)) {
436     if (pthread_equal(prevSignalThread, myId)) {
437       // First time here. Try to dump the stack trace without symbolization.
438       // If we still fail, well, we're mightily screwed, so we do nothing the
439       // next time around.
440       if (!gInRecursiveSignalHandler.exchange(true)) {
441         print("Entered fatal signal handler recursively. We're in trouble.\n");
442         dumpStackTrace(false);  // no symbolization
443       }
444       return;
445     }
446
447     // Wait a while, try again.
448     timespec ts;
449     ts.tv_sec = 0;
450     ts.tv_nsec = 100L * 1000 * 1000;  // 100ms
451     nanosleep(&ts, nullptr);
452
453     prevSignalThread = kInvalidThreadId;
454   }
455
456   dumpTimeInfo();
457   dumpSignalInfo(signum, info);
458   dumpStackTrace(true);  // with symbolization
459
460   // Run user callbacks
461   gFatalSignalCallbackRegistry->run();
462 }
463
464 void signalHandler(int signum, siginfo_t* info, void* uctx) {
465   SCOPE_EXIT { flush(); };
466   innerSignalHandler(signum, info, uctx);
467
468   gSignalThread = kInvalidThreadId;
469   // Kill ourselves with the previous handler.
470   callPreviousSignalHandler(signum);
471 }
472
473 }  // namespace
474
475 void addFatalSignalCallback(SignalCallback cb) {
476   gFatalSignalCallbackRegistry->add(cb);
477 }
478
479 void installFatalSignalCallbacks() {
480   gFatalSignalCallbackRegistry->markInstalled();
481 }
482
483 namespace {
484
485 std::atomic<bool> gAlreadyInstalled;
486
487 }  // namespace
488
489 void installFatalSignalHandler() {
490   if (gAlreadyInstalled.exchange(true)) {
491     // Already done.
492     return;
493   }
494
495   struct sigaction sa;
496   memset(&sa, 0, sizeof(sa));
497   sigemptyset(&sa.sa_mask);
498   // By default signal handlers are run on the signaled thread's stack.
499   // In case of stack overflow running the SIGSEGV signal handler on
500   // the same stack leads to another SIGSEGV and crashes the program.
501   // Use SA_ONSTACK, so alternate stack is used (only if configured via
502   // sigaltstack).
503   sa.sa_flags |= SA_SIGINFO | SA_ONSTACK;
504   sa.sa_sigaction = &signalHandler;
505
506   for (auto p = kFatalSignals; p->name; ++p) {
507     CHECK_ERR(sigaction(p->number, &sa, &p->oldAction));
508   }
509 }
510
511 }}  // namespaces