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发送该信号