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