Android Native crash monitor on device and host

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#endif
412  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 mean
264  // our "info" arg holds an undefined value.
265  if (!have_siginfo(signal_number)) {
266    info = nullptr;
267  }
268
269  log_signal_summary(signal_number, info);
270
271  send_debuggerd_packet(info);
272
273  // We need to return from the signal handler so that debuggerd can dump the
274  // thread that crashed, but returning here does not guarantee that the signal
275  // will be thrown again, even for SIGSEGV and friends, since the signal could
276  // have been sent manually. Resend the signal with rt_tgsigqueueinfo(2) to
277  // preserve the SA_SIGINFO contents.
278  signal(signal_number, SIG_DFL);
279
280  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 kernels
289    // that contain commit 66dd34a (3.9+). The manpage claims to only allow
290    // negative si_code values that are not SI_TKILL, but 66dd34a changed the
291    // check to allow all si_code values in calls coming from inside the house.
292  }
293
294  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}
301
302__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;
308
309  // Use the alternate signal stack if available so we can catch stack overflows.
310  action.sa_flags |= SA_ONSTACK;
311
312  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#endif
320  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;
401
402  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#endif
412  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}
419
420}  // namespace art


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值