Android 信号处理:虚拟机ART: SIGQUIT

shell command kill对应的代码

# kill
usage:    kill [-s signame | -signum | -signame] { job | pid | pgrp } ...
    kill -l [exit_status ...]


1] 根据输出搜索 “-s signame” 找到对应的代码位置


external/mksh/src/funcs.c -> c_kill

2] kill -l 列出所有使用的singal


 kill -l
 1    HUP Hangup                        33     33 Signal 33
 2    INT Interrupt                     34     34 Signal 34
 3   QUIT Quit                          35     35 Signal 35
 4    ILL Illegal instruction           36     36 Signal 36
 5   TRAP Trap                          37     37 Signal 37
 6   ABRT Aborted                       38     38 Signal 38
 7    BUS Bus error                     39     39 Signal 39
 8    FPE Floating point exception      40     40 Signal 40
 9   KILL Killed                        41     41 Signal 41
10   USR1 User signal 1                 42     42 Signal 42
11   SEGV Segmentation fault            43     43 Signal 43
12   USR2 User signal 2                 44     44 Signal 44
13   PIPE Broken pipe                   45     45 Signal 45
14   ALRM Alarm clock                   46     46 Signal 46
15   TERM Terminated                    47     47 Signal 47
16 STKFLT Stack fault                   48     48 Signal 48
17   CHLD Child exited                  49     49 Signal 49
18   CONT Continue                      50     50 Signal 50
19   STOP Stopped (signal)              51     51 Signal 51
20   TSTP Stopped                       52     52 Signal 52
21   TTIN Stopped (tty input)           53     53 Signal 53
22   TTOU Stopped (tty output)          54     54 Signal 54
23    URG Urgent I/O condition          55     55 Signal 55
24   XCPU CPU time limit exceeded       56     56 Signal 56
25   XFSZ File size limit exceeded      57     57 Signal 57
26 VTALRM Virtual timer expired         58     58 Signal 58
27   PROF Profiling timer expired       59     59 Signal 59
28  WINCH Window size changed           60     60 Signal 60
29     IO I/O possible                  61     61 Signal 61
30    PWR Power failure                 62     62 Signal 62
31    SYS Bad system call               63     63 Signal 63
32     32 Signal 32                     64     64 Signal 64

3] kill [-s signame | -signum | -signame] { job | pid | pgrp } ...


从这看出kill的使用方法kill -s QUIT/ kill -3/ kill -QUIT pid

4] kill命令的实现就是调用 函数: int kill(pid_t pid, int sig);

art Runtime信号处理

信号捕捉注册

art/runtime/runtime.cc
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
  BlockSignals();
}

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);
  signals.Block();
}

信号的处理线程


void Runtime::StartSignalCatcher() {
  if (!is_zygote_) {
    signal_catcher_ = new SignalCatcher(stack_trace_file_, use_tombstoned_traces_);
  }
}

Runtime::Start() -> Runtime::InitNonZygoteOrPostFork -> Runtime::StartSignalCatcher

SignalCatcher::SignalCatcher(const std::string& stack_trace_file,
                             bool use_tombstoned_stack_trace_fd)
    : stack_trace_file_(stack_trace_file),
      use_tombstoned_stack_trace_fd_(use_tombstoned_stack_trace_fd),
      lock_("SignalCatcher lock"),
      cond_("SignalCatcher::cond_", lock_),
      thread_(nullptr) {
  // Create a raw pthread; its start routine will attach to the runtime.
  CHECK_PTHREAD_CALL(pthread_create, (&pthread_, nullptr, &Run, this), "signal catcher thread");
  }
}

void* SignalCatcher::Run(void* arg) {
  SignalCatcher* signal_catcher = reinterpret_cast<SignalCatcher*>(arg);

  Runtime* runtime = Runtime::Current();
  CHECK(runtime->AttachCurrentThread("Signal Catcher", true, runtime->GetSystemThreadGroup(),
                                     !runtime->IsAotCompiler()));

  // Set up mask with signals we want to handle.
  SignalSet signals;
  signals.Add(SIGQUIT);
  signals.Add(SIGUSR1);

  while (true) {
    int signal_number = signal_catcher->WaitForSignal(self, signals);

    switch (signal_number) {
    case SIGQUIT:
      signal_catcher->HandleSigQuit();
      break;
    case SIGUSR1:
      signal_catcher->HandleSigUsr1();
      break;
    default:
      LOG(ERROR) << "Unexpected signal %d" << signal_number;
      break;
    }
  }
}

SigQuit处理函数

void SignalCatcher::HandleSigQuit() {
  Runtime* runtime = Runtime::Current();
  std::ostringstream os;
  os << "\n"
      << "----- pid " << getpid() << " at " << GetIsoDate() << " -----\n";

  DumpCmdLine(os);

  // Note: The strings "Build fingerprint:" and "ABI:" are chosen to match the format used by
  // debuggerd. This allows, for example, the stack tool to work.
  std::string fingerprint = runtime->GetFingerprint();
  os << "Build fingerprint: '" << (fingerprint.empty() ? "unknown" : fingerprint) << "'\n";
  os << "ABI: '" << GetInstructionSetString(runtime->GetInstructionSet()) << "'\n";

  os << "Build type: " << (kIsDebugBuild ? "debug" : "optimized") << "\n";

  runtime->DumpForSigQuit(os);

  os << "----- end " << getpid() << " -----\n";
  Output(os.str());
}

这里展现了c++的多态性(多个class使用相同的名字DumpForSigQuit)
void Runtime::DumpForSigQuit(std::ostream& os) {
  GetClassLinker()->DumpForSigQuit(os);
  GetInternTable()->DumpForSigQuit(os);
  GetJavaVM()->DumpForSigQuit(os);
  // GetHeap()->DumpForSigQuit(os);
  oat_file_manager_->DumpForSigQuit(os);
  if (GetJit() != nullptr) {
    GetJit()->DumpForSigQuit(os);
  } else {
    os << "Running non JIT\n";
  }
  DumpDeoptimizations(os);
  TrackedAllocators::Dump(os);
  os << "\n";

  thread_list_->DumpForSigQuit(os);
  BaseMutex::DumpAll(os);

  // Inform anyone else who is interested in SigQuit.
  {
    ScopedObjectAccess soa(Thread::Current());
    callbacks_->SigQuit();
  }
}

其中主要是thread_list_->DumpForSigQuit(os) dump各线程的栈,这里没有看出怎样保存dump到文件
  Output(os.str());

bool SignalCatcher::OpenStackTraceFile(android::base::unique_fd* tombstone_fd,
                                       android::base::unique_fd* output_fd) {

  int fd = open(stack_trace_file_.c_str(), O_APPEND | O_CREAT | O_WRONLY, 0666);
  output_fd->reset(fd);
  return true;
}

void SignalCatcher::Output(const std::string& s) {
  android::base::unique_fd tombstone_fd;
  android::base::unique_fd output_fd;
  if (!OpenStackTraceFile(&tombstone_fd, &output_fd)) {
    LOG(INFO) << s;
    return;
  }


  std::unique_ptr<File> file(new File(output_fd.release(), true /* check_usage */));
  bool success = file->WriteFully(s.data(), s.size());

  const std::string output_path_msg = (use_tombstoned_stack_trace_fd_) ?
      "[tombstoned]" : stack_trace_file_;

  LOG(INFO) << "Wrote stack traces to '" << output_path_msg << "'";
}

zygote64: Wrote stack traces to '/data/anr/traces.txt'

哪里会发送信号SIGQUIT

https://blog.csdn.net/u011279649/article/details/53909003
appNotResponding的代码处理流程

FC不会发送信号SIGQUIT而是SIGKILL, ANR发送该信号

猜你喜欢

转载自blog.csdn.net/u011279649/article/details/81661778