• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
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 #include <cxxabi.h>
18 #include <dlfcn.h>
19 #include <pthread.h>
20 #include <signal.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/syscall.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <unwind.h>
29 
30 #include "perfetto/base/build_config.h"
31 #include "perfetto/base/file_utils.h"
32 
33 // Some glibc headers hit this when using signals.
34 #pragma GCC diagnostic push
35 #if defined(__clang__)
36 #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
37 #endif
38 
39 #if defined(NDEBUG)
40 #error This translation unit should not be used in release builds
41 #endif
42 
43 #if !PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
44 #error This translation unit should not be used in non-standalone builds
45 #endif
46 
47 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
48     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
49 #include <backtrace.h>
50 #endif
51 
52 namespace {
53 
54 constexpr size_t kDemangledNameLen = 4096;
55 
56 bool g_sighandler_registered = false;
57 char* g_demangled_name = nullptr;
58 
59 struct SigHandler {
60   int sig_num;
61   struct sigaction old_handler;
62 };
63 
64 SigHandler g_signals[] = {{SIGSEGV, {}}, {SIGILL, {}}, {SIGTRAP, {}},
65                           {SIGABRT, {}}, {SIGBUS, {}}, {SIGFPE, {}}};
66 
67 template <typename T>
Print(const T & str)68 void Print(const T& str) {
69   perfetto::base::WriteAll(STDERR_FILENO, str, sizeof(str));
70 }
71 
72 template <typename T>
PrintHex(T n)73 void PrintHex(T n) {
74   for (unsigned i = 0; i < sizeof(n) * 8; i += 4) {
75     char nibble = static_cast<char>(n >> (sizeof(n) * 8 - i - 4)) & 0x0F;
76     char c = (nibble < 10) ? '0' + nibble : 'A' + nibble - 10;
77     perfetto::base::WriteAll(STDERR_FILENO, &c, 1);
78   }
79 }
80 
81 struct StackCrawlState {
StackCrawlState__anon498eee610111::StackCrawlState82   StackCrawlState(uintptr_t* frames_arg, size_t max_depth_arg)
83       : frames(frames_arg),
84         frame_count(0),
85         max_depth(max_depth_arg),
86         skip_count(1) {}
87 
88   uintptr_t* frames;
89   size_t frame_count;
90   size_t max_depth;
91   size_t skip_count;
92 };
93 
TraceStackFrame(_Unwind_Context * context,void * arg)94 _Unwind_Reason_Code TraceStackFrame(_Unwind_Context* context, void* arg) {
95   StackCrawlState* state = static_cast<StackCrawlState*>(arg);
96   uintptr_t ip = _Unwind_GetIP(context);
97 
98   if (ip != 0 && state->skip_count) {
99     state->skip_count--;
100     return _URC_NO_REASON;
101   }
102 
103   state->frames[state->frame_count++] = ip;
104   if (state->frame_count >= state->max_depth)
105     return _URC_END_OF_STACK;
106   return _URC_NO_REASON;
107 }
108 
RestoreSignalHandlers()109 void RestoreSignalHandlers() {
110   for (size_t i = 0; i < sizeof(g_signals) / sizeof(g_signals[0]); i++)
111     sigaction(g_signals[i].sig_num, &g_signals[i].old_handler, nullptr);
112 }
113 
114 // Note: use only async-safe functions inside this.
SignalHandler(int sig_num,siginfo_t * info,void *)115 void SignalHandler(int sig_num, siginfo_t* info, void* /*ucontext*/) {
116   // Restore the old handlers.
117   RestoreSignalHandlers();
118 
119   Print("\n------------------ BEGINNING OF CRASH ------------------\n");
120   Print("Signal: ");
121   if (sig_num == SIGSEGV) {
122     Print("Segmentation fault");
123   } else if (sig_num == SIGILL) {
124     Print("Illegal instruction (possibly unaligned access)");
125   } else if (sig_num == SIGTRAP) {
126     Print("Trap");
127   } else if (sig_num == SIGABRT) {
128     Print("Abort");
129   } else if (sig_num == SIGBUS) {
130     Print("Bus Error (possibly unmapped memory access)");
131   } else if (sig_num == SIGFPE) {
132     Print("Floating point exception");
133   } else {
134     Print("Unexpected signal ");
135     PrintHex(static_cast<uint32_t>(sig_num));
136   }
137 
138   Print("\n");
139 
140   Print("Fault addr: ");
141   PrintHex(reinterpret_cast<uintptr_t>(info->si_addr));
142   Print("\n\nBacktrace:\n");
143 
144   const size_t kMaxFrames = 64;
145   uintptr_t frames[kMaxFrames];
146   StackCrawlState unwind_state(frames, kMaxFrames);
147   _Unwind_Backtrace(&TraceStackFrame, &unwind_state);
148 
149 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
150     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
151   auto bt_error = [](void*, const char* msg, int) { Print(msg); };
152   struct backtrace_state* bt_state =
153       backtrace_create_state(nullptr, 0, bt_error, nullptr);
154 #endif
155 
156   for (uint8_t i = 0; i < unwind_state.frame_count; i++) {
157     struct SymbolInfo {
158       char sym_name[255];
159       char file_name[255];
160     };
161     SymbolInfo sym{{}, {}};
162 
163 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
164     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
165     auto symbolize_callback = [](void* data, uintptr_t /*pc*/,
166                                  const char* filename, int lineno,
167                                  const char* function) -> int {
168       SymbolInfo* psym = reinterpret_cast<SymbolInfo*>(data);
169       if (function)
170         strncpy(psym->sym_name, function, sizeof(psym->sym_name));
171       if (filename) {
172         snprintf(psym->file_name, sizeof(psym->file_name), "%s:%d", filename,
173                  lineno);
174       }
175       return 0;
176     };
177     backtrace_pcinfo(bt_state, frames[i], symbolize_callback, bt_error, &sym);
178 #else
179     Dl_info dl_info = {};
180     int res = dladdr(reinterpret_cast<void*>(frames[i]), &dl_info);
181     if (res && dl_info.dli_sname)
182       strncpy(sym.sym_name, dl_info.dli_sname, sizeof(sym.sym_name));
183 #endif
184 
185     Print("\n#");
186     PrintHex(i);
187     Print("  ");
188 
189     if (sym.sym_name[0]) {
190       int ignored;
191       size_t len = kDemangledNameLen;
192       char* demangled =
193           abi::__cxa_demangle(sym.sym_name, g_demangled_name, &len, &ignored);
194       if (demangled) {
195         strncpy(sym.sym_name, demangled, sizeof(sym.sym_name));
196         // In the exceptional case of demangling something > kDemangledNameLen,
197         // __cxa_demangle will realloc(). In that case the malloc()-ed pointer
198         // might be moved.
199         g_demangled_name = demangled;
200       }
201       perfetto::base::WriteAll(STDERR_FILENO, sym.sym_name,
202                                strlen(sym.sym_name));
203     } else {
204       Print("0x");
205       PrintHex(frames[i]);
206     }
207     if (sym.file_name[0]) {
208       Print("\n     ");
209       perfetto::base::WriteAll(STDERR_FILENO, sym.file_name,
210                                strlen(sym.file_name));
211     }
212     Print("\n");
213   }
214 
215   Print("------------------ END OF CRASH ------------------\n");
216 
217   // info->si_code <= 0 iff SI_FROMUSER (SI_FROMKERNEL otherwise).
218   if (info->si_code <= 0 || sig_num == SIGABRT) {
219 // This signal was triggered by somebody sending us the signal with kill().
220 // In order to retrigger it, we have to queue a new signal by calling
221 // kill() ourselves.  The special case (si_pid == 0 && sig == SIGABRT) is
222 // due to the kernel sending a SIGABRT from a user request via SysRQ.
223 #if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
224     if (kill(getpid(), sig_num) < 0) {
225 #else
226     if (syscall(__NR_tgkill, getpid(), syscall(__NR_gettid), sig_num) < 0) {
227 #endif
228       // If we failed to kill ourselves (e.g. because a sandbox disallows us
229       // to do so), we instead resort to terminating our process. This will
230       // result in an incorrect exit code.
231       _exit(1);
232     }
233   }
234 }
235 
236 // __attribute__((constructor)) causes a static initializer that automagically
237 // early runs this function before the main().
238 void __attribute__((constructor)) EnableStacktraceOnCrashForDebug();
239 
240 void EnableStacktraceOnCrashForDebug() {
241   if (g_sighandler_registered)
242     return;
243   g_sighandler_registered = true;
244 
245   // Pre-allocate the string for __cxa_demangle() to reduce the risk of that
246   // invoking realloc() within the signal handler.
247   g_demangled_name = reinterpret_cast<char*>(malloc(kDemangledNameLen));
248   struct sigaction sigact = {};
249   sigact.sa_sigaction = &SignalHandler;
250   sigact.sa_flags = static_cast<decltype(sigact.sa_flags)>(
251       SA_RESTART | SA_SIGINFO | SA_RESETHAND);
252   for (size_t i = 0; i < sizeof(g_signals) / sizeof(g_signals[0]); i++)
253     sigaction(g_signals[i].sig_num, &sigact, &g_signals[i].old_handler);
254 
255   // Prevents fork()-ed processes to inherit the crash signal handlers. This
256   // significantly speeds up gtest death tests, because running the unwinder
257   // takes some hundreds of ms. These signal handlers are completely useless
258   // in death tests because: (i) death tests are expected to crash by design;
259   // (ii) the output of death test is not visible.
260   pthread_atfork(nullptr, nullptr, &RestoreSignalHandlers);
261 }
262 
263 }  // namespace
264 
265 #pragma GCC diagnostic pop
266