通过上文,查看socket name = "kTombstonedJavaTraceSocketName" 的socket服务端
路径为:system/core/debuggerd/tombstoned/tombstoned.cpp
6.1
main(),java_trace_socket就是在5.12中,链接过来的socket客户端的连接标志,通过这个连接标志,创建一个listener,回调函数为crash_accept_cb()
int main(int, char* []) {
if (kJavaTraceDumpsEnabled) {
//从tombstoned_client.cpp的tombstoned_connect所在的客户端连接过来的
const int java_trace_socket = android_get_control_socket(kTombstonedJavaTraceSocketName);
evutil_make_socket_nonblocking(java_trace_socket);
//当触发这个listener监听的时候,回调会在crash_accept_cb中实现
evconnlistener* java_trace_listener =
evconnlistener_new(base, crash_accept_cb, CrashQueue::for_anrs(), LEV_OPT_CLOSE_ON_FREE,
-1 /* backlog */, java_trace_socket);
}
}
6.2
crash_accept_cb(),在这个回调函数中,创建了一个Crash对象,然后调用了回调函数crash_request_cb,将创建的Crash对象传入
参数:sockfd = android_get_control_socket(kTombstonedJavaTraceSocketName)
static void crash_accept_cb(evconnlistener* listener, evutil_socket_t sockfd, sockaddr*, int,
void*) {
event_base* base = evconnlistener_get_base(listener);
Crash* crash = new Crash();
//继续调用了回调crash_request_cb
event* crash_event = event_new(base, sockfd, EV_TIMEOUT | EV_READ, crash_request_cb, crash);
//crash->crash_socket_fd = java_trace_socket = android_get_control_socket(kTombstonedJavaTraceSocketName) 从tombstoned_client.cpp的tombstoned_connect所在的客户端连接过来的
crash->crash_socket_fd.reset(sockfd);
crash->crash_event = crash_event;
event_add(crash_event, &timeout);
}
6.3
crash_request_cb(),这个函数中,会接收到tombstoned_client.cpp客户端通过write发送的数据,接收载体为request = {packet.packet_type = CrashPacketType::kDumpRequest, packet.packet.dump_request.pid = pid, packet.packet.dump_request.dump_type = dump_type}
参数:sockfd = android_get_control_socket(kTombstonedJavaTraceSocketName) ,arg = new Crash()
//sockfd = java_trace_socket = android_get_control_socket(kTombstonedJavaTraceSocketName) 从tombstoned_client.cpp的tombstoned_connect所在的客户端连接过来的
//arg = crash = new Crash();
static void crash_request_cb(evutil_socket_t sockfd, short ev, void* arg) {
ssize_t rc;
//获取crash_accept_cb中的new Crash()
Crash* crash = static_cast(arg);
TombstonedCrashPacket request = {};
//read从sockfd中读取客户端发送的数据到request
//request = {packet.packet_type = CrashPacketType::kDumpRequest, packet.packet.dump_request.pid = pid, packet.packet.dump_request.dump_type = dump_type}
rc = TEMP_FAILURE_RETRY(read(sockfd, &request, sizeof(request)));
//给crash_type赋值 这里crash_type = kDebuggerdJavaBacktrace,所以执行if,给crash_pid赋值为pid
crash->crash_type = request.packet.dump_request.dump_type;
if (crash->crash_type != kDebuggerdJavaBacktrace) {
crash->crash_pid = request.packet.dump_request.pid;
}
//maybe_enqueue_crash方法意思是num_concurrent_dumps_ == max_concurrent_dumps_时,将这个crash存入请求队列queued_requests_,排队处理,然后return true。否则执行else
if (CrashQueue::for_crash(crash)->maybe_enqueue_crash(crash)) {
LOG(INFO) << "enqueueing crash request for pid " << crash->crash_pid;
} else {
perform_request(crash);
}
return;
}
6.4
perform_request(),在这个方法中,会通过调用GetIntercept()方法,传入output_fd,获取4.4中,被赋值的intercept->output_fd = rcv_fd = pipe_write.get(),然后通过SendFileDescriptors()方法,将response和output_fd一起发送给5.12中的socket客户端
//crash->crash_type = kDebuggerdJavaBacktrace
//crash->crash_pid = pid
static void perform_request(Crash* crash) {
unique_fd output_fd;
//执行完GetIntercept()后,返回的intercepted在正常情况下为true,所以不执行if内的逻辑
//pid = crash->crash_pid
//dump_type = crash->crash_type = kDebuggerdJavaBacktrace
//output_fd = intercept->output_fd = std::move(rcv_fd) = pipe_write.get()
bool intercepted = intercept_manager->GetIntercept(crash->crash_pid, crash->crash_type, &output_fd);
TombstonedCrashPacket response = {
.packet_type = CrashPacketType::kPerformDump
};
//由于crash->crash_socket_fd = java_trace_socket = android_get_control_socket(kTombstonedJavaTraceSocketName) 从tombstoned_client.cpp的tombstoned_connect所在的客户端连接过来的
//所以SendFileDescriptors,发送response = {.packet_type = CrashPacketType::kPerformDump} output_fd = pipe_write.get();
//到tombstoned_client.cpp的tombstoned_connect中的ReceiveFileDescriptors收取,
ssize_t rc =
SendFileDescriptors(crash->crash_socket_fd, &response, sizeof(response), output_fd.get());
output_fd.reset();
}
--------------------------------------------------------------------------------------------------------------------
//pid = crash->crash_pid
//dump_type = crash->crash_type = kDebuggerdJavaBacktrace
//out_fd = output_fd(是新申明的一个空指针)
bool InterceptManager::GetIntercept(pid_t pid, DebuggerdDumpType dump_type, android::base::unique_fd* out_fd) {
//判断pid是否相同
auto it = this->intercepts.find(pid);
if (it == this->intercepts.end()) {
return false;
}
//判断dump的type是否相同
if (dump_type == kDebuggerdAnyIntercept) {
LOG(INFO) << "found registered intercept of type " << it->second->dump_type
<< " for requested type kDebuggerdAnyIntercept";
} else if (it->second->dump_type != dump_type) {
LOG(WARNING) << "found non-matching intercept of type " << it->second->dump_type
<< " for requested type: " << dump_type;
return false;
}
auto intercept = std::move(it->second);
this->intercepts.erase(it);
InterceptResponse response = {};
response.status = InterceptStatus::kStarted;
//将&response写入intercept->sockfd代表的文件中,即将response写入给 intercept_socket = android_get_control_socket(kTombstonedInterceptSocketName) 代表的socket客户端中
TEMP_FAILURE_RETRY(write(intercept->sockfd, &response, sizeof(response)));
//将out_fd指向的地址变为intercept->output_fd指向的地址,intercept->output_fd是在intercept_request_cb中赋值的
//intercept->output_fd = std::move(rcv_fd) = pipe_write.get()
*out_fd = std::move(intercept->output_fd);
return true;
}
6.5 system/core/debuggerd/client/debuggerd_client.cpp
bool debuggerd_trigger_dump(pid_t tid, DebuggerdDumpType dump_type, unsigned int timeout_ms,
unique_fd output_fd) {
//接收 6.4 中,发出的response
rc = TEMP_FAILURE_RETRY(recv(set_timeout(sockfd.get()), &response, sizeof(response), MSG_TRUNC));
if (response.status != InterceptStatus::kStarted) {
response.error_message[sizeof(response.error_message) - 1] = '\0';
LOG(ERROR) << "libdebuggerd_client: tombstoned reported failure: " << response.error_message;
return false;
}
// Forward output from the pipe to the output fd.
while (true) {
//创建pollfd类型的结构体pfd
struct pollfd pfd = {
.fd = pipe_read.get(), .events = POLLIN, .revents = 0,
};
//通过poll,将pfd加入监视当中
rc = poll(&pfd, 1, remaining_ms);
char buf[1024];
//通过read方法,读取管道pipe_read.get()中的数据到buf数据
rc = TEMP_FAILURE_RETRY(read(pipe_read.get(), buf, sizeof(buf)));
//将buf数组中的内容,写入到文件描述符output_fd指向的文件,从434中可知output_fd = "/data/anr/anr_Date"的文件描述符
//所以这个地方是将数据写入到了/data/anr/anr_Date文件中。
if (!android::base::WriteFully(output_fd.get(), buf, rc)) {
PLOG(ERROR) << "libdebuggerd_client: error while writing";
return false;
}
}
//至此,anr的log已经打印完毕
LOG(INFO) << "libdebuggerd_client: done dumping process " << pid;
return true;
}