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 "runtime_common.h"
18 
19 #include <signal.h>
20 
21 #include <cinttypes>
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25 
26 #include "android-base/stringprintf.h"
27 
28 #include "base/logging.h"
29 #include "base/macros.h"
30 #include "base/mutex.h"
31 #include "native_stack_dump.h"
32 #include "thread-inl.h"
33 #include "thread_list.h"
34 
35 namespace art {
36 
37 using android::base::StringPrintf;
38 
39 static constexpr bool kUseSigRTTimeout = true;
40 static constexpr bool kDumpNativeStackOnTimeout = true;
41 
GetSignalName(int signal_number)42 const char* GetSignalName(int signal_number) {
43   switch (signal_number) {
44     case SIGABRT: return "SIGABRT";
45     case SIGBUS: return "SIGBUS";
46     case SIGFPE: return "SIGFPE";
47     case SIGILL: return "SIGILL";
48     case SIGPIPE: return "SIGPIPE";
49     case SIGSEGV: return "SIGSEGV";
50 #if defined(SIGSTKFLT)
51     case SIGSTKFLT: return "SIGSTKFLT";
52 #endif
53     case SIGTRAP: return "SIGTRAP";
54   }
55   return "??";
56 }
57 
GetSignalCodeName(int signal_number,int signal_code)58 const char* GetSignalCodeName(int signal_number, int signal_code) {
59   // Try the signal-specific codes...
60   switch (signal_number) {
61     case SIGILL:
62       switch (signal_code) {
63         case ILL_ILLOPC: return "ILL_ILLOPC";
64         case ILL_ILLOPN: return "ILL_ILLOPN";
65         case ILL_ILLADR: return "ILL_ILLADR";
66         case ILL_ILLTRP: return "ILL_ILLTRP";
67         case ILL_PRVOPC: return "ILL_PRVOPC";
68         case ILL_PRVREG: return "ILL_PRVREG";
69         case ILL_COPROC: return "ILL_COPROC";
70         case ILL_BADSTK: return "ILL_BADSTK";
71       }
72       break;
73     case SIGBUS:
74       switch (signal_code) {
75         case BUS_ADRALN: return "BUS_ADRALN";
76         case BUS_ADRERR: return "BUS_ADRERR";
77         case BUS_OBJERR: return "BUS_OBJERR";
78       }
79       break;
80     case SIGFPE:
81       switch (signal_code) {
82         case FPE_INTDIV: return "FPE_INTDIV";
83         case FPE_INTOVF: return "FPE_INTOVF";
84         case FPE_FLTDIV: return "FPE_FLTDIV";
85         case FPE_FLTOVF: return "FPE_FLTOVF";
86         case FPE_FLTUND: return "FPE_FLTUND";
87         case FPE_FLTRES: return "FPE_FLTRES";
88         case FPE_FLTINV: return "FPE_FLTINV";
89         case FPE_FLTSUB: return "FPE_FLTSUB";
90       }
91       break;
92     case SIGSEGV:
93       switch (signal_code) {
94         case SEGV_MAPERR: return "SEGV_MAPERR";
95         case SEGV_ACCERR: return "SEGV_ACCERR";
96 #if defined(SEGV_BNDERR)
97         case SEGV_BNDERR: return "SEGV_BNDERR";
98 #endif
99       }
100       break;
101     case SIGTRAP:
102       switch (signal_code) {
103         case TRAP_BRKPT: return "TRAP_BRKPT";
104         case TRAP_TRACE: return "TRAP_TRACE";
105       }
106       break;
107   }
108   // Then the other codes...
109   switch (signal_code) {
110     case SI_USER:     return "SI_USER";
111 #if defined(SI_KERNEL)
112     case SI_KERNEL:   return "SI_KERNEL";
113 #endif
114     case SI_QUEUE:    return "SI_QUEUE";
115     case SI_TIMER:    return "SI_TIMER";
116     case SI_MESGQ:    return "SI_MESGQ";
117     case SI_ASYNCIO:  return "SI_ASYNCIO";
118 #if defined(SI_SIGIO)
119     case SI_SIGIO:    return "SI_SIGIO";
120 #endif
121 #if defined(SI_TKILL)
122     case SI_TKILL:    return "SI_TKILL";
123 #endif
124   }
125   // Then give up...
126   return "?";
127 }
128 
129 struct UContext {
UContextart::UContext130   explicit UContext(void* raw_context)
131       : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {}
132 
133   void Dump(std::ostream& os) const;
134 
135   void DumpRegister32(std::ostream& os, const char* name, uint32_t value) const;
136   void DumpRegister64(std::ostream& os, const char* name, uint64_t value) const;
137 
138   void DumpX86Flags(std::ostream& os, uint32_t flags) const;
139   // Print some of the information from the status register (CPSR on ARMv7, PSTATE on ARMv8).
140   template <typename RegisterType>
141   void DumpArmStatusRegister(std::ostream& os, RegisterType status_register) const;
142 
143   mcontext_t& context;
144 };
145 
Dump(std::ostream & os) const146 void UContext::Dump(std::ostream& os) const {
147 #if defined(__APPLE__) && defined(__i386__)
148   DumpRegister32(os, "eax", context->__ss.__eax);
149   DumpRegister32(os, "ebx", context->__ss.__ebx);
150   DumpRegister32(os, "ecx", context->__ss.__ecx);
151   DumpRegister32(os, "edx", context->__ss.__edx);
152   os << '\n';
153 
154   DumpRegister32(os, "edi", context->__ss.__edi);
155   DumpRegister32(os, "esi", context->__ss.__esi);
156   DumpRegister32(os, "ebp", context->__ss.__ebp);
157   DumpRegister32(os, "esp", context->__ss.__esp);
158   os << '\n';
159 
160   DumpRegister32(os, "eip", context->__ss.__eip);
161   os << "                   ";
162   DumpRegister32(os, "eflags", context->__ss.__eflags);
163   DumpX86Flags(os, context->__ss.__eflags);
164   os << '\n';
165 
166   DumpRegister32(os, "cs",  context->__ss.__cs);
167   DumpRegister32(os, "ds",  context->__ss.__ds);
168   DumpRegister32(os, "es",  context->__ss.__es);
169   DumpRegister32(os, "fs",  context->__ss.__fs);
170   os << '\n';
171   DumpRegister32(os, "gs",  context->__ss.__gs);
172   DumpRegister32(os, "ss",  context->__ss.__ss);
173 #elif defined(__linux__) && defined(__i386__)
174   DumpRegister32(os, "eax", context.gregs[REG_EAX]);
175   DumpRegister32(os, "ebx", context.gregs[REG_EBX]);
176   DumpRegister32(os, "ecx", context.gregs[REG_ECX]);
177   DumpRegister32(os, "edx", context.gregs[REG_EDX]);
178   os << '\n';
179 
180   DumpRegister32(os, "edi", context.gregs[REG_EDI]);
181   DumpRegister32(os, "esi", context.gregs[REG_ESI]);
182   DumpRegister32(os, "ebp", context.gregs[REG_EBP]);
183   DumpRegister32(os, "esp", context.gregs[REG_ESP]);
184   os << '\n';
185 
186   DumpRegister32(os, "eip", context.gregs[REG_EIP]);
187   os << "                   ";
188   DumpRegister32(os, "eflags", context.gregs[REG_EFL]);
189   DumpX86Flags(os, context.gregs[REG_EFL]);
190   os << '\n';
191 
192   DumpRegister32(os, "cs",  context.gregs[REG_CS]);
193   DumpRegister32(os, "ds",  context.gregs[REG_DS]);
194   DumpRegister32(os, "es",  context.gregs[REG_ES]);
195   DumpRegister32(os, "fs",  context.gregs[REG_FS]);
196   os << '\n';
197   DumpRegister32(os, "gs",  context.gregs[REG_GS]);
198   DumpRegister32(os, "ss",  context.gregs[REG_SS]);
199 #elif defined(__linux__) && defined(__x86_64__)
200   DumpRegister64(os, "rax", context.gregs[REG_RAX]);
201   DumpRegister64(os, "rbx", context.gregs[REG_RBX]);
202   DumpRegister64(os, "rcx", context.gregs[REG_RCX]);
203   DumpRegister64(os, "rdx", context.gregs[REG_RDX]);
204   os << '\n';
205 
206   DumpRegister64(os, "rdi", context.gregs[REG_RDI]);
207   DumpRegister64(os, "rsi", context.gregs[REG_RSI]);
208   DumpRegister64(os, "rbp", context.gregs[REG_RBP]);
209   DumpRegister64(os, "rsp", context.gregs[REG_RSP]);
210   os << '\n';
211 
212   DumpRegister64(os, "r8 ", context.gregs[REG_R8]);
213   DumpRegister64(os, "r9 ", context.gregs[REG_R9]);
214   DumpRegister64(os, "r10", context.gregs[REG_R10]);
215   DumpRegister64(os, "r11", context.gregs[REG_R11]);
216   os << '\n';
217 
218   DumpRegister64(os, "r12", context.gregs[REG_R12]);
219   DumpRegister64(os, "r13", context.gregs[REG_R13]);
220   DumpRegister64(os, "r14", context.gregs[REG_R14]);
221   DumpRegister64(os, "r15", context.gregs[REG_R15]);
222   os << '\n';
223 
224   DumpRegister64(os, "rip", context.gregs[REG_RIP]);
225   os << "   ";
226   DumpRegister32(os, "eflags", context.gregs[REG_EFL]);
227   DumpX86Flags(os, context.gregs[REG_EFL]);
228   os << '\n';
229 
230   DumpRegister32(os, "cs",  (context.gregs[REG_CSGSFS]) & 0x0FFFF);
231   DumpRegister32(os, "gs",  (context.gregs[REG_CSGSFS] >> 16) & 0x0FFFF);
232   DumpRegister32(os, "fs",  (context.gregs[REG_CSGSFS] >> 32) & 0x0FFFF);
233   os << '\n';
234 #elif defined(__linux__) && defined(__arm__)
235   DumpRegister32(os, "r0", context.arm_r0);
236   DumpRegister32(os, "r1", context.arm_r1);
237   DumpRegister32(os, "r2", context.arm_r2);
238   DumpRegister32(os, "r3", context.arm_r3);
239   os << '\n';
240 
241   DumpRegister32(os, "r4", context.arm_r4);
242   DumpRegister32(os, "r5", context.arm_r5);
243   DumpRegister32(os, "r6", context.arm_r6);
244   DumpRegister32(os, "r7", context.arm_r7);
245   os << '\n';
246 
247   DumpRegister32(os, "r8", context.arm_r8);
248   DumpRegister32(os, "r9", context.arm_r9);
249   DumpRegister32(os, "r10", context.arm_r10);
250   DumpRegister32(os, "fp", context.arm_fp);
251   os << '\n';
252 
253   DumpRegister32(os, "ip", context.arm_ip);
254   DumpRegister32(os, "sp", context.arm_sp);
255   DumpRegister32(os, "lr", context.arm_lr);
256   DumpRegister32(os, "pc", context.arm_pc);
257   os << '\n';
258 
259   DumpRegister32(os, "cpsr", context.arm_cpsr);
260   DumpArmStatusRegister(os, context.arm_cpsr);
261   os << '\n';
262 #elif defined(__linux__) && defined(__aarch64__)
263   for (size_t i = 0; i <= 30; ++i) {
264     std::string reg_name = "x" + std::to_string(i);
265     DumpRegister64(os, reg_name.c_str(), context.regs[i]);
266     if (i % 4 == 3) {
267       os << '\n';
268     }
269   }
270   os << '\n';
271 
272   DumpRegister64(os, "sp", context.sp);
273   DumpRegister64(os, "pc", context.pc);
274   os << '\n';
275 
276   DumpRegister64(os, "pstate", context.pstate);
277   DumpArmStatusRegister(os, context.pstate);
278   os << '\n';
279 #else
280   // TODO: Add support for MIPS32 and MIPS64.
281   os << "Unknown architecture/word size/OS in ucontext dump";
282 #endif
283 }
284 
DumpRegister32(std::ostream & os,const char * name,uint32_t value) const285 void UContext::DumpRegister32(std::ostream& os, const char* name, uint32_t value) const {
286   os << StringPrintf(" %6s: 0x%08x", name, value);
287 }
288 
DumpRegister64(std::ostream & os,const char * name,uint64_t value) const289 void UContext::DumpRegister64(std::ostream& os, const char* name, uint64_t value) const {
290   os << StringPrintf(" %6s: 0x%016" PRIx64, name, value);
291 }
292 
DumpX86Flags(std::ostream & os,uint32_t flags) const293 void UContext::DumpX86Flags(std::ostream& os, uint32_t flags) const {
294   os << " [";
295   if ((flags & (1 << 0)) != 0) {
296     os << " CF";
297   }
298   if ((flags & (1 << 2)) != 0) {
299     os << " PF";
300   }
301   if ((flags & (1 << 4)) != 0) {
302     os << " AF";
303   }
304   if ((flags & (1 << 6)) != 0) {
305     os << " ZF";
306   }
307   if ((flags & (1 << 7)) != 0) {
308     os << " SF";
309   }
310   if ((flags & (1 << 8)) != 0) {
311     os << " TF";
312   }
313   if ((flags & (1 << 9)) != 0) {
314     os << " IF";
315   }
316   if ((flags & (1 << 10)) != 0) {
317     os << " DF";
318   }
319   if ((flags & (1 << 11)) != 0) {
320     os << " OF";
321   }
322   os << " ]";
323 }
324 
325 template <typename RegisterType>
DumpArmStatusRegister(std::ostream & os,RegisterType status_register) const326 void UContext::DumpArmStatusRegister(std::ostream& os, RegisterType status_register) const {
327   // Condition flags.
328   constexpr RegisterType kFlagV = 1U << 28;
329   constexpr RegisterType kFlagC = 1U << 29;
330   constexpr RegisterType kFlagZ = 1U << 30;
331   constexpr RegisterType kFlagN = 1U << 31;
332 
333   os << " [";
334   if ((status_register & kFlagN) != 0) {
335     os << " N";
336   }
337   if ((status_register & kFlagZ) != 0) {
338     os << " Z";
339   }
340   if ((status_register & kFlagC) != 0) {
341     os << " C";
342   }
343   if ((status_register & kFlagV) != 0) {
344     os << " V";
345   }
346   os << " ]";
347 }
348 
GetTimeoutSignal()349 int GetTimeoutSignal() {
350 #if defined(__APPLE__)
351   // Mac does not support realtime signals.
352   UNUSED(kUseSigRTTimeout);
353   return -1;
354 #else
355   return kUseSigRTTimeout ? (SIGRTMIN + 2) : -1;
356 #endif
357 }
358 
IsTimeoutSignal(int signal_number)359 static bool IsTimeoutSignal(int signal_number) {
360   return signal_number == GetTimeoutSignal();
361 }
362 
363 #if defined(__APPLE__)
364 // On macOS, clang complains about art::HandleUnexpectedSignalCommon's
365 // stack frame size being too large; disable that warning locally.
366 #pragma GCC diagnostic push
367 #pragma GCC diagnostic ignored "-Wframe-larger-than="
368 #endif
369 
HandleUnexpectedSignalCommon(int signal_number,siginfo_t * info,void * raw_context,bool running_on_linux)370 void HandleUnexpectedSignalCommon(int signal_number,
371                                   siginfo_t* info,
372                                   void* raw_context,
373                                   bool running_on_linux) {
374   bool handle_timeout_signal = running_on_linux;
375   bool dump_on_stderr = running_on_linux;
376 
377   static bool handling_unexpected_signal = false;
378   if (handling_unexpected_signal) {
379     LogHelper::LogLineLowStack(__FILE__,
380                                __LINE__,
381                                ::android::base::FATAL_WITHOUT_ABORT,
382                                "HandleUnexpectedSignal reentered\n");
383     if (handle_timeout_signal) {
384       if (IsTimeoutSignal(signal_number)) {
385         // Ignore a recursive timeout.
386         return;
387       }
388     }
389     _exit(1);
390   }
391   handling_unexpected_signal = true;
392 
393   gAborting++;  // set before taking any locks
394   MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
395 
396   bool has_address = (signal_number == SIGILL || signal_number == SIGBUS ||
397                       signal_number == SIGFPE || signal_number == SIGSEGV);
398 
399   OsInfo os_info;
400   const char* cmd_line = GetCmdLine();
401   if (cmd_line == nullptr) {
402     cmd_line = "<unset>";  // Because no-one called InitLogging.
403   }
404   pid_t tid = GetTid();
405   std::string thread_name(GetThreadName(tid));
406   UContext thread_context(raw_context);
407   Backtrace thread_backtrace(raw_context);
408 
409   std::ostringstream stream;
410   stream << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"
411          << StringPrintf("Fatal signal %d (%s), code %d (%s)",
412                          signal_number,
413                          GetSignalName(signal_number),
414                          info->si_code,
415                          GetSignalCodeName(signal_number, info->si_code))
416          << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << '\n'
417          << "OS: " << Dumpable<OsInfo>(os_info) << '\n'
418          << "Cmdline: " << cmd_line << '\n'
419          << "Thread: " << tid << " \"" << thread_name << "\"" << '\n'
420          << "Registers:\n" << Dumpable<UContext>(thread_context) << '\n'
421          << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace) << '\n';
422   if (dump_on_stderr) {
423     // Note: We are using cerr directly instead of LOG macros to ensure even just partial output
424     //       makes it out. That means we lose the "dalvikvm..." prefix, but that is acceptable
425     //       considering this is an abort situation.
426     std::cerr << stream.str() << std::flush;
427   } else {
428     LOG(FATAL_WITHOUT_ABORT) << stream.str() << std::flush;
429   }
430   if (kIsDebugBuild && signal_number == SIGSEGV) {
431     PrintFileToLog("/proc/self/maps", LogSeverity::FATAL_WITHOUT_ABORT);
432   }
433 
434   Runtime* runtime = Runtime::Current();
435   if (runtime != nullptr) {
436     if (handle_timeout_signal && IsTimeoutSignal(signal_number)) {
437       // Special timeout signal. Try to dump all threads.
438       // Note: Do not use DumpForSigQuit, as that might disable native unwind, but the native parts
439       //       are of value here.
440       runtime->GetThreadList()->Dump(std::cerr, kDumpNativeStackOnTimeout);
441       std::cerr << std::endl;
442     }
443 
444     if (dump_on_stderr) {
445       std::cerr << "Fault message: " << runtime->GetFaultMessage() << std::endl;
446     } else {
447       LOG(FATAL_WITHOUT_ABORT) << "Fault message: " << runtime->GetFaultMessage();
448     }
449   }
450 }
451 
452 #if defined(__APPLE__)
453 #pragma GCC diagnostic pop
454 #endif
455 
InitPlatformSignalHandlersCommon(void (* newact)(int,siginfo_t *,void *),struct sigaction * oldact,bool handle_timeout_signal)456 void InitPlatformSignalHandlersCommon(void (*newact)(int, siginfo_t*, void*),
457                                       struct sigaction* oldact,
458                                       bool handle_timeout_signal) {
459   struct sigaction action;
460   memset(&action, 0, sizeof(action));
461   sigemptyset(&action.sa_mask);
462   action.sa_sigaction = newact;
463   // Use the three-argument sa_sigaction handler.
464   action.sa_flags |= SA_SIGINFO;
465   // Use the alternate signal stack so we can catch stack overflows.
466   action.sa_flags |= SA_ONSTACK;
467 
468   int rc = 0;
469   rc += sigaction(SIGABRT, &action, oldact);
470   rc += sigaction(SIGBUS, &action, oldact);
471   rc += sigaction(SIGFPE, &action, oldact);
472   rc += sigaction(SIGILL, &action, oldact);
473   rc += sigaction(SIGPIPE, &action, oldact);
474   rc += sigaction(SIGSEGV, &action, oldact);
475 #if defined(SIGSTKFLT)
476   rc += sigaction(SIGSTKFLT, &action, oldact);
477 #endif
478   rc += sigaction(SIGTRAP, &action, oldact);
479   // Special dump-all timeout.
480   if (handle_timeout_signal && GetTimeoutSignal() != -1) {
481     rc += sigaction(GetTimeoutSignal(), &action, oldact);
482   }
483   CHECK_EQ(rc, 0);
484 }
485 
486 }  // namespace art
487