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();