fault_handler

 

art/runtime/fault_handler.cc
FaultManager fault_manager;

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
}

static void art_fault_handler(int sig, siginfo_t* info, void* context) {
  fault_manager.HandleFault(sig, info, context);
}

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
      }
    }
  }

...................................... }

 

art/sigchainlib/sigchain.cc
static SignalAction user_sigactions[_NSIG]; //控制每个信号的独特处理方式

// Claim a signal chain for a particular signal.
extern "C" void ClaimSignalChain(int signal, struct sigaction* oldaction) {
  CheckSignalValid(signal);

  user_sigactions[signal].Claim(*oldaction);
}

 

class SignalAction {
 public:
  SignalAction() : claimed_(false), uses_old_style_(false), special_handler_(nullptr) {
  }

  // Claim the signal and keep the action specified.
  void Claim(const struct sigaction& action) {
    action_ = action;
    claimed_ = true;
  }

  // Unclaim the signal and restore the old action.
  void Unclaim(int signal) {
    claimed_ = false;
    sigaction(signal, &action_, nullptr);        // Restore old action.
  }

  // Get the action associated with this signal.
  const struct sigaction& GetAction() const {
    return action_;
  }

  // Is the signal claimed?
  bool IsClaimed() const {
    return claimed_;
  }

  // Change the recorded action to that specified.
  // If oldstyle is true then this action is from an older style signal()
  // call as opposed to sigaction().  In this case the sa_handler is
  // used when invoking the user's handler.
  void SetAction(const struct sigaction& action, bool oldstyle) {
    action_ = action;
    uses_old_style_ = oldstyle;
  }

  bool OldStyle() const {
    return uses_old_style_;
  }

  void SetSpecialHandler(SpecialSignalHandlerFn fn) {
    special_handler_ = fn;
  }

  SpecialSignalHandlerFn GetSpecialHandler() {
    return special_handler_;
  }

 private:
  struct sigaction action_;                 // Action to be performed.
  bool claimed_;                            // Whether signal is claimed or not.
  bool uses_old_style_;                     // Action is created using signal().  Use sa_handler.
  SpecialSignalHandlerFn special_handler_;  // A special handler executed before user handlers.
};

fault_manager是在Runtime::Init()中初始化的

fault_manager.Init();

posted @ 2015-09-24 21:37  牧 天  阅读(717)  评论(0)    收藏  举报