1/*
2 * Copyright (C) 2011 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.h"
18
19#include <signal.h>
20#include <string.h>
21#include <sys/utsname.h>
22#include <inttypes.h>
23
24#include "base/logging.h"
25#include "base/mutex.h"
26#include "base/stringprintf.h"
27#include "thread-inl.h"
28#include "utils.h"
29
30namespace art {
31
32static constexpr bool kDumpHeapObjectOnSigsevg = false;
33
34struct Backtrace {
35  void Dump(std::ostream& os) {
36    DumpNativeStack(os, GetTid(), "\t");
37  }
38};
39
40struct OsInfo {
41  void Dump(std::ostream& os) {
42    utsname info;
43    uname(&info);
44    // Linux 2.6.38.8-gg784 (x86_64)
45    // Darwin 11.4.0 (x86_64)
46    os << info.sysname << " " << info.release << " (" << info.machine << ")";
47  }
48};
49
50static const char* GetSignalName(int signal_number) {
51  switch (signal_number) {
52    case SIGABRT: return "SIGABRT";
53    case SIGBUS: return "SIGBUS";
54    case SIGFPE: return "SIGFPE";
55    case SIGILL: return "SIGILL";
56    case SIGPIPE: return "SIGPIPE";
57    case SIGSEGV: return "SIGSEGV";
58#if defined(SIGSTKFLT)
59    case SIGSTKFLT: return "SIGSTKFLT";
60#endif
61    case SIGTRAP: return "SIGTRAP";
62  }
63  return "??";
64}
65
66static const char* GetSignalCodeName(int signal_number, int signal_code) {
67  // Try the signal-specific codes...
68  switch (signal_number) {
69    case SIGILL:
70      switch (signal_code) {
71        case ILL_ILLOPC: return "ILL_ILLOPC";
72        case ILL_ILLOPN: return "ILL_ILLOPN";
73        case ILL_ILLADR: return "ILL_ILLADR";
74        case ILL_ILLTRP: return "ILL_ILLTRP";
75        case ILL_PRVOPC: return "ILL_PRVOPC";
76        case ILL_PRVREG: return "ILL_PRVREG";
77        case ILL_COPROC: return "ILL_COPROC";
78        case ILL_BADSTK: return "ILL_BADSTK";
79      }
80      break;
81    case SIGBUS:
82      switch (signal_code) {
83        case BUS_ADRALN: return "BUS_ADRALN";
84        case BUS_ADRERR: return "BUS_ADRERR";
85        case BUS_OBJERR: return "BUS_OBJERR";
86      }
87      break;
88    case SIGFPE:
89      switch (signal_code) {
90        case FPE_INTDIV: return "FPE_INTDIV";
91        case FPE_INTOVF: return "FPE_INTOVF";
92        case FPE_FLTDIV: return "FPE_FLTDIV";
93        case FPE_FLTOVF: return "FPE_FLTOVF";
94        case FPE_FLTUND: return "FPE_FLTUND";
95        case FPE_FLTRES: return "FPE_FLTRES";
96        case FPE_FLTINV: return "FPE_FLTINV";
97        case FPE_FLTSUB: return "FPE_FLTSUB";
98      }
99      break;
100    case SIGSEGV:
101      switch (signal_code) {
102        case SEGV_MAPERR: return "SEGV_MAPERR";
103        case SEGV_ACCERR: return "SEGV_ACCERR";
104      }
105      break;
106    case SIGTRAP:
107      switch (signal_code) {
108        case TRAP_BRKPT: return "TRAP_BRKPT";
109        case TRAP_TRACE: return "TRAP_TRACE";
110      }
111      break;
112  }
113  // Then the other codes...
114  switch (signal_code) {
115    case SI_USER:     return "SI_USER";
116#if defined(SI_KERNEL)
117    case SI_KERNEL:   return "SI_KERNEL";
118#endif
119    case SI_QUEUE:    return "SI_QUEUE";
120    case SI_TIMER:    return "SI_TIMER";
121    case SI_MESGQ:    return "SI_MESGQ";
122    case SI_ASYNCIO:  return "SI_ASYNCIO";
123#if defined(SI_SIGIO)
124    case SI_SIGIO:    return "SI_SIGIO";
125#endif
126#if defined(SI_TKILL)
127    case SI_TKILL:    return "SI_TKILL";
128#endif
129  }
130  // Then give up...
131  return "?";
132}
133
134struct UContext {
135  explicit UContext(void* raw_context) : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {}
136
137  void Dump(std::ostream& os) {
138    // TODO: support non-x86 hosts (not urgent because this code doesn't run on targets).
139#if defined(__APPLE__) && defined(__i386__)
140    DumpRegister32(os, "eax", context->__ss.__eax);
141    DumpRegister32(os, "ebx", context->__ss.__ebx);
142    DumpRegister32(os, "ecx", context->__ss.__ecx);
143    DumpRegister32(os, "edx", context->__ss.__edx);
144    os << '\n';
145
146    DumpRegister32(os, "edi", context->__ss.__edi);
147    DumpRegister32(os, "esi", context->__ss.__esi);
148    DumpRegister32(os, "ebp", context->__ss.__ebp);
149    DumpRegister32(os, "esp", context->__ss.__esp);
150    os << '\n';
151
152    DumpRegister32(os, "eip", context->__ss.__eip);
153    os << "                   ";
154    DumpRegister32(os, "eflags", context->__ss.__eflags);
155    DumpX86Flags(os, context->__ss.__eflags);
156    os << '\n';
157
158    DumpRegister32(os, "cs",  context->__ss.__cs);
159    DumpRegister32(os, "ds",  context->__ss.__ds);
160    DumpRegister32(os, "es",  context->__ss.__es);
161    DumpRegister32(os, "fs",  context->__ss.__fs);
162    os << '\n';
163    DumpRegister32(os, "gs",  context->__ss.__gs);
164    DumpRegister32(os, "ss",  context->__ss.__ss);
165#elif defined(__linux__) && defined(__i386__)
166    DumpRegister32(os, "eax", context.gregs[REG_EAX]);
167    DumpRegister32(os, "ebx", context.gregs[REG_EBX]);
168    DumpRegister32(os, "ecx", context.gregs[REG_ECX]);
169    DumpRegister32(os, "edx", context.gregs[REG_EDX]);
170    os << '\n';
171
172    DumpRegister32(os, "edi", context.gregs[REG_EDI]);
173    DumpRegister32(os, "esi", context.gregs[REG_ESI]);
174    DumpRegister32(os, "ebp", context.gregs[REG_EBP]);
175    DumpRegister32(os, "esp", context.gregs[REG_ESP]);
176    os << '\n';
177
178    DumpRegister32(os, "eip", context.gregs[REG_EIP]);
179    os << "                   ";
180    DumpRegister32(os, "eflags", context.gregs[REG_EFL]);
181    DumpX86Flags(os, context.gregs[REG_EFL]);
182    os << '\n';
183
184    DumpRegister32(os, "cs",  context.gregs[REG_CS]);
185    DumpRegister32(os, "ds",  context.gregs[REG_DS]);
186    DumpRegister32(os, "es",  context.gregs[REG_ES]);
187    DumpRegister32(os, "fs",  context.gregs[REG_FS]);
188    os << '\n';
189    DumpRegister32(os, "gs",  context.gregs[REG_GS]);
190    DumpRegister32(os, "ss",  context.gregs[REG_SS]);
191#elif defined(__linux__) && defined(__x86_64__)
192    DumpRegister64(os, "rax", context.gregs[REG_RAX]);
193    DumpRegister64(os, "rbx", context.gregs[REG_RBX]);
194    DumpRegister64(os, "rcx", context.gregs[REG_RCX]);
195    DumpRegister64(os, "rdx", context.gregs[REG_RDX]);
196    os << '\n';
197
198    DumpRegister64(os, "rdi", context.gregs[REG_RDI]);
199    DumpRegister64(os, "rsi", context.gregs[REG_RSI]);
200    DumpRegister64(os, "rbp", context.gregs[REG_RBP]);
201    DumpRegister64(os, "rsp", context.gregs[REG_RSP]);
202    os << '\n';
203
204    DumpRegister64(os, "r8 ", context.gregs[REG_R8]);
205    DumpRegister64(os, "r9 ", context.gregs[REG_R9]);
206    DumpRegister64(os, "r10", context.gregs[REG_R10]);
207    DumpRegister64(os, "r11", context.gregs[REG_R11]);
208    os << '\n';
209
210    DumpRegister64(os, "r12", context.gregs[REG_R12]);
211    DumpRegister64(os, "r13", context.gregs[REG_R13]);
212    DumpRegister64(os, "r14", context.gregs[REG_R14]);
213    DumpRegister64(os, "r15", context.gregs[REG_R15]);
214    os << '\n';
215
216    DumpRegister64(os, "rip", context.gregs[REG_RIP]);
217    os << "   ";
218    DumpRegister32(os, "eflags", context.gregs[REG_EFL]);
219    DumpX86Flags(os, context.gregs[REG_EFL]);
220    os << '\n';
221
222    DumpRegister32(os, "cs",  (context.gregs[REG_CSGSFS]) & 0x0FFFF);
223    DumpRegister32(os, "gs",  (context.gregs[REG_CSGSFS] >> 16) & 0x0FFFF);
224    DumpRegister32(os, "fs",  (context.gregs[REG_CSGSFS] >> 32) & 0x0FFFF);
225    os << '\n';
226#else
227    os << "Unknown architecture/word size/OS in ucontext dump";
228#endif
229  }
230
231  void DumpRegister32(std::ostream& os, const char* name, uint32_t value) {
232    os << StringPrintf(" %6s: 0x%08x", name, value);
233  }
234
235  void DumpRegister64(std::ostream& os, const char* name, uint64_t value) {
236    os << StringPrintf(" %6s: 0x%016" PRIx64, name, value);
237  }
238
239  void DumpX86Flags(std::ostream& os, uint32_t flags) {
240    os << " [";
241    if ((flags & (1 << 0)) != 0) {
242      os << " CF";
243    }
244    if ((flags & (1 << 2)) != 0) {
245      os << " PF";
246    }
247    if ((flags & (1 << 4)) != 0) {
248      os << " AF";
249    }
250    if ((flags & (1 << 6)) != 0) {
251      os << " ZF";
252    }
253    if ((flags & (1 << 7)) != 0) {
254      os << " SF";
255    }
256    if ((flags & (1 << 8)) != 0) {
257      os << " TF";
258    }
259    if ((flags & (1 << 9)) != 0) {
260      os << " IF";
261    }
262    if ((flags & (1 << 10)) != 0) {
263      os << " DF";
264    }
265    if ((flags & (1 << 11)) != 0) {
266      os << " OF";
267    }
268    os << " ]";
269  }
270
271  mcontext_t& context;
272};
273
274void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
275  static bool handlingUnexpectedSignal = false;
276  if (handlingUnexpectedSignal) {
277    LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
278    LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n");
279    _exit(1);
280  }
281  handlingUnexpectedSignal = true;
282
283  gAborting++;  // set before taking any locks
284  MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
285
286  bool has_address = (signal_number == SIGILL || signal_number == SIGBUS ||
287                      signal_number == SIGFPE || signal_number == SIGSEGV);
288
289  OsInfo os_info;
290  const char* cmd_line = GetCmdLine();
291  if (cmd_line == NULL) {
292    cmd_line = "<unset>";  // Because no-one called InitLogging.
293  }
294  pid_t tid = GetTid();
295  std::string thread_name(GetThreadName(tid));
296  UContext thread_context(raw_context);
297  Backtrace thread_backtrace;
298
299  LOG(INTERNAL_FATAL) << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"
300                      << StringPrintf("Fatal signal %d (%s), code %d (%s)",
301                                      signal_number, GetSignalName(signal_number),
302                                      info->si_code,
303                                      GetSignalCodeName(signal_number, info->si_code))
304                      << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << "\n"
305                      << "OS: " << Dumpable<OsInfo>(os_info) << "\n"
306                      << "Cmdline: " << cmd_line << "\n"
307                      << "Thread: " << tid << " \"" << thread_name << "\"\n"
308                      << "Registers:\n" << Dumpable<UContext>(thread_context) << "\n"
309                      << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace);
310  Runtime* runtime = Runtime::Current();
311  if (runtime != nullptr) {
312    gc::Heap* heap = runtime->GetHeap();
313    LOG(INTERNAL_FATAL) << "Fault message: " << runtime->GetFaultMessage();
314    if (kDumpHeapObjectOnSigsevg && heap != nullptr && info != nullptr) {
315      LOG(INTERNAL_FATAL) << "Dump heap object at fault address: ";
316      heap->DumpObject(LOG(INTERNAL_FATAL), reinterpret_cast<mirror::Object*>(info->si_addr));
317    }
318  }
319  if (getenv("debug_db_uid") != NULL || getenv("art_wait_for_gdb_on_crash") != NULL) {
320    LOG(INTERNAL_FATAL) << "********************************************************\n"
321                        << "* Process " << getpid() << " thread " << tid << " \"" << thread_name << "\""
322                        << " has been suspended while crashing.\n"
323                        << "* Attach gdb:\n"
324                        << "*     gdb -p " << tid << "\n"
325                        << "********************************************************\n";
326    // Wait for debugger to attach.
327    while (true) {
328    }
329  }
330#ifdef __linux__
331  // Remove our signal handler for this signal...
332  struct sigaction action;
333  memset(&action, 0, sizeof(action));
334  sigemptyset(&action.sa_mask);
335  action.sa_handler = SIG_DFL;
336  sigaction(signal_number, &action, NULL);
337  // ...and re-raise so we die with the appropriate status.
338  kill(getpid(), signal_number);
339#else
340  exit(EXIT_FAILURE);
341#endif
342}
343
344void Runtime::InitPlatformSignalHandlers() {
345  // On the host, we don't have debuggerd to dump a stack for us when something unexpected happens.
346  struct sigaction action;
347  memset(&action, 0, sizeof(action));
348  sigemptyset(&action.sa_mask);
349  action.sa_sigaction = HandleUnexpectedSignal;
350  // Use the three-argument sa_sigaction handler.
351  action.sa_flags |= SA_SIGINFO;
352  // Use the alternate signal stack so we can catch stack overflows.
353  action.sa_flags |= SA_ONSTACK;
354
355  int rc = 0;
356  rc += sigaction(SIGABRT, &action, NULL);
357  rc += sigaction(SIGBUS, &action, NULL);
358  rc += sigaction(SIGFPE, &action, NULL);
359  rc += sigaction(SIGILL, &action, NULL);
360  rc += sigaction(SIGPIPE, &action, NULL);
361  rc += sigaction(SIGSEGV, &action, NULL);
362#if defined(SIGSTKFLT)
363  rc += sigaction(SIGSTKFLT, &action, NULL);
364#endif
365  rc += sigaction(SIGTRAP, &action, NULL);
366  CHECK_EQ(rc, 0);
367}
368
369}  // namespace art
370