Zygote signal sigaction

 

bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
  .................. BlockSignals(); InitPlatformSignalHandlers();
// Always initialize the signal chain so that any calls to sigaction get // correctly routed to the next in the chain regardless of whether we // have claimed the signal or not. // 加载如下两个库: // dlsym(RTLD_NEXT, "sigaction"); // dlsym(RTLD_DEFAULT, "sigprocmask"); InitializeSignalChain(); if (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_) { //所有信号都要交给fault_manager来处理,所以这个很早就初始化了 fault_manager.Init(); // These need to be in a specific order. The null point check handler must be // after the suspend check and stack overflow check handlers. if (implicit_suspend_checks_) { //false suspend_handler_ = new SuspensionHandler(&fault_manager); } if (implicit_so_checks_) { //true stack_overflow_handler_ = new StackOverflowHandler(&fault_manager); } if (implicit_null_checks_) { //ture null_pointer_handler_ = new NullPointerHandler(&fault_manager); } if (kEnableJavaStackTraceHandler) { //false new JavaStackTraceHandler(&fault_manager); } } ............................ }

 

//阻塞了4个信号SIGPIPE SIGQUIT SIGUSR SIGSTKFLT
void Runtime::BlockSignals() {
  SignalSet signals;
  signals.Add(SIGPIPE);
  // SIGQUIT is used to dump the runtime's state (including stack traces).
  signals.Add(SIGQUIT);
  // SIGUSR1 is used to initiate a GC.
  signals.Add(SIGUSR1);
#if defined(HAVE_ANDROID_OS) && defined(MTK_DUMMY_PREDUMP)
  signals.Add(SIGSTKFLT);
#endif
  signals.Block();
}

 

//signal注册函数NativeCrashSigHandler
void Runtime::InitPlatformSignalHandlers() {
  bool enableHtcSigHandler = false;
#ifdef HAVE_ANDROID_OS
  char prop_value[PROPERTY_VALUE_MAX];
  property_get("persist.dalvik.sighandle.enable", prop_value, IsShippingRom() ? "0" : "1");
  enableHtcSigHandler = (strcmp(prop_value, "0") != 0);
#endif

  if (enableHtcSigHandler) {
#if defined(__LP64__)   
    // Follow bionic/libc/bionic/pthread_create.cpp to install alter stack on LP64 platform
    // 另外建立新的信号栈,将信号在新的信号栈里面处理,防止OOM时将原有栈覆盖
stack_t ss; ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (ss.ss_sp != MAP_FAILED) { ss.ss_size = SIGSTKSZ; ss.ss_flags = 0; int ret = sigaltstack(&ss, NULL); LOG(INFO) << StringPrintf("do sigaltstack at %s, size: %zd-byte, ret: %d", __FUNCTION__, ss.ss_size, ret); } else { LOG(INFO) << StringPrintf("do mmap altstack at %s, size: %d-byte, MAP_FAILED", __FUNCTION__, SIGSTKSZ); } #endif struct sigaction action; memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); action.sa_sigaction = NativeCrashSigHandler;  //用户自定义signal处理函数 // Use the three-argument sa_sigaction handler. action.sa_flags |= SA_SIGINFO; // Use the alternate signal stack so we can catch stack overflows. action.sa_flags |= SA_ONSTACK; //有这个flags 信号才会在新的信号栈上处理,否则信号栈无用 // initialize for backup native crash handler memset(&gOldActionSIGABRT, 0, sizeof(gOldActionSIGABRT)); memset(&gOldActionSIGSEGV, 0, sizeof(gOldActionSIGSEGV)); // Register the native crash signal. int rc = 0; rc += sigaction(SIGABRT, &action, &gOldActionSIGABRT); rc += sigaction(SIGSEGV, &action, &gOldActionSIGSEGV); CHECK_EQ(rc, 0); } }

 

 

// 加载如下两个库:
// dlsym(RTLD_NEXT, "sigaction");
// dlsym(RTLD_DEFAULT, "sigprocmask");
InitializeSignalChain();

// signal注册函数art_fault_handler
// ClaimSignalChain(SIGSEGV, oldaction_)
//将这个两个handler加入fault_manager中
fault_manager.Init();  
void FaultManager::Init() {
  CHECK(!initialized_);
  struct sigaction action;
  SetUpArtAction(&action);

  // Set our signal handler now.
  int e = sigaction(SIGSEGV, &action, &oldaction_);
  if (e != 0) {
    VLOG(signals) << "Failed to claim SEGV: " << strerror(errno);
  }
  // Make sure our signal handler is called before any user handlers.
  ClaimSignalChain(SIGSEGV, &oldaction_);
  initialized_ = true;
}
static void SetUpArtAction(struct sigaction* action) {
  action->sa_sigaction = art_fault_handler; 
  sigemptyset(&action->sa_mask);
  action->sa_flags = SA_SIGINFO | SA_ONSTACK;
#if !defined(__APPLE__) && !defined(__mips__)
  action->sa_restorer = nullptr;
#endif
}

extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction) {
  CheckSignalValid(signal);
  user_sigactions[signal].Claim(*oldaction); //这里很重要
}

stack_overflow_handler_ = new StackOverflowHandler(&fault_manager);
null_pointer_handler_ = new NullPointerHandler(&fault_manager);

 

void FaultManager::HandleFault(int sig, siginfo_t* info, void* context) {
  // BE CAREFUL ALLOCATING HERE INCLUDING USING LOG(...)
  //
  // If malloc calls abort, it will be holding its lock.
  // If the handler tries to call malloc, it will deadlock.
  VLOG(signals) << "Handling fault";
  if (IsInGeneratedCode(info, context, true)) {
    VLOG(signals) << "in generated code, looking for handler";
    for (const auto& handler : generated_code_handlers_) {
      VLOG(signals) << "invoking Action on handler " << handler;
      if (handler->Action(sig, info, context)) {
#ifdef TEST_NESTED_SIGNAL
        // In test mode we want to fall through to stack trace handler
        // on every signal (in reality this will cause a crash on the first
        // signal).
        break;
#else
        // We have handled a signal so it's time to return from the
        // signal handler to the appropriate place.
        return;
#endif
      }
    }
  }

  // We hit a signal we didn't handle.  This might be something for which
  // we can give more information about so call all registered handlers to see
  // if it is.
  for (const auto& handler : other_handlers_) {
    if (handler->Action(sig, info, context)) {
      return;
    }
  }

  // Set a breakpoint in this function to catch unhandled signals.
  art_sigsegv_fault(); //这个就只打了一行log

  //如果系统能处理(也就是我们注册的FaultHandler能处理)则不会调用InvokeUserSignalHandler()
  //先系统处理,系统处理不了才给用户处理
  // Pass this on to the next handler in the chain, or the default if none.
  InvokeUserSignalHandler(sig, info, context);  //这里调用NativeCrashSigHandler
}

其余代码参考:http://www.cnblogs.com/muhe221/articles/4720822.html

sigaction(SIGSEGV, &action, &oldaction_);这个oldaction_(也就是注册NativeCrashSigHandler函数对应的action)被Claimed ClaimSignalChain(SIGSEGV, &oldaction_);
也就是说SIGSEGV signal处理方式:先用art_fault_handler函数处理,如果处理不了,则由signalchain的方式处理(即调用NativeCrashSigHandler)

SIGABRT则是直接由NativeCrashSigHandler来处理

posted @ 2015-10-22 22:54  牧 天  阅读(806)  评论(0)    收藏  举报