Android Native crash monitor on device and host

来源:互联网 发布:淘宝买ps3 编辑:程序博客网 时间:2024/05/29 10:41

target process will receive corresponding signal if a native crash happen. The signals include,

403  rc += sigaction(SIGABRT, &action, nullptr);404  rc += sigaction(SIGBUS, &action, nullptr);405  rc += sigaction(SIGFPE, &action, nullptr);406  rc += sigaction(SIGILL, &action, nullptr);407  rc += sigaction(SIGPIPE, &action, nullptr);408  rc += sigaction(SIGSEGV, &action, nullptr);409#if defined(SIGSTKFLT)410  rc += sigaction(SIGSTKFLT, &action, nullptr);411#endif412  rc += sigaction(SIGTRAP, &action, nullptr);

On device, signal catcher is implemented in bionic/linker/debugger.cpp

262static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) {263  // It's possible somebody cleared the SA_SIGINFO flag, which would mean264  // our "info" arg holds an undefined value.265  if (!have_siginfo(signal_number)) {266    info = nullptr;267  }268269  log_signal_summary(signal_number, info);270271  send_debuggerd_packet(info);272273  // We need to return from the signal handler so that debuggerd can dump the274  // thread that crashed, but returning here does not guarantee that the signal275  // will be thrown again, even for SIGSEGV and friends, since the signal could276  // have been sent manually. Resend the signal with rt_tgsigqueueinfo(2) to277  // preserve the SA_SIGINFO contents.278  signal(signal_number, SIG_DFL);279280  struct siginfo si;281  if (!info) {282    memset(&si, 0, sizeof(si));283    si.si_code = SI_USER;284    si.si_pid = getpid();285    si.si_uid = getuid();286    info = &si;287  } else if (info->si_code >= 0 || info->si_code == SI_TKILL) {288    // rt_tgsigqueueinfo(2)'s documentation appears to be incorrect on kernels289    // that contain commit 66dd34a (3.9+). The manpage claims to only allow290    // negative si_code values that are not SI_TKILL, but 66dd34a changed the291    // check to allow all si_code values in calls coming from inside the house.292  }293294  int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), signal_number, info);295  if (rc != 0) {296    __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to resend signal during crash: %s",297                      strerror(errno));298    _exit(0);299  }300}301302__LIBC_HIDDEN__ void debuggerd_init() {303  struct sigaction action;304  memset(&action, 0, sizeof(action));305  sigemptyset(&action.sa_mask);306  action.sa_sigaction = debuggerd_signal_handler;307  action.sa_flags = SA_RESTART | SA_SIGINFO;308309  // Use the alternate signal stack if available so we can catch stack overflows.310  action.sa_flags |= SA_ONSTACK;311312  sigaction(SIGABRT, &action, nullptr);313  sigaction(SIGBUS, &action, nullptr);314  sigaction(SIGFPE, &action, nullptr);315  sigaction(SIGILL, &action, nullptr);316  sigaction(SIGSEGV, &action, nullptr);317#if defined(SIGSTKFLT)318  sigaction(SIGSTKFLT, &action, nullptr);319#endif320  sigaction(SIGTRAP, &action, nullptr);321}322

After native crash happen, the signal catcher will send command to debuggerd daemon.

debugger daemon will engrave_tombstone method to dump tombstone info into a file under /data/tombstone/ folder.

Meanwhile, it will send command to NativeCrashListener via socket. Native Crash listener will generate a report under/data/system/dropbox folder.


On host, it is implemented in art/runtime/runtime_linux.cc

391void Runtime::InitPlatformSignalHandlers() {392  // On the host, we don't have debuggerd to dump a stack for us when something unexpected happens.393  struct sigaction action;394  memset(&action, 0, sizeof(action));395  sigemptyset(&action.sa_mask);396  action.sa_sigaction = HandleUnexpectedSignal;397  // Use the three-argument sa_sigaction handler.398  action.sa_flags |= SA_SIGINFO;399  // Use the alternate signal stack so we can catch stack overflows.400  action.sa_flags |= SA_ONSTACK;401402  int rc = 0;403  rc += sigaction(SIGABRT, &action, nullptr);404  rc += sigaction(SIGBUS, &action, nullptr);405  rc += sigaction(SIGFPE, &action, nullptr);406  rc += sigaction(SIGILL, &action, nullptr);407  rc += sigaction(SIGPIPE, &action, nullptr);408  rc += sigaction(SIGSEGV, &action, nullptr);409#if defined(SIGSTKFLT)410  rc += sigaction(SIGSTKFLT, &action, nullptr);411#endif412  rc += sigaction(SIGTRAP, &action, nullptr);413  // Special dump-all timeout.414  if (GetTimeoutSignal() != -1) {415    rc += sigaction(GetTimeoutSignal(), &action, nullptr);416  }417  CHECK_EQ(rc, 0);418}419420}  // namespace art


原创粉丝点击