上文中说到,通过socket去访问服务端,服务端的socket是在哪接受请求的呢,就在
[system](http://axr.htc.com/source/xref/Q_Mainline/system/)/[core](http://axr.htc.com/source/xref/Q_Mainline/system/core/)/[debuggerd](http://axr.htc.com/source/xref/Q_Mainline/system/core/debuggerd/)/[tombstoned](http://axr.htc.com/source/xref/Q_Mainline/system/core/debuggerd/tombstoned/)/[tombstoned.cpp](http://axr.htc.com/source/xref/Q_Mainline/system/core/debuggerd/tombstoned/tombstoned.cpp)中
4.1
main(),获取socket name = kTombstonedInterceptSocketName 的socket客户端索引fd, 然后通过libevent库,实现event的轮循处理
int main(int, char* []) {
//获取socket name = kTombstonedInterceptSocketName 的socket客户端索引fd
int intercept_socket = android_get_control_socket(kTombstonedInterceptSocketName);
//使用libevent库,创建一个base event (https://blog.csdn.net/Lemon_tea666/article/details/92637297 , https://blog.csdn.net/znimade/article/details/72575420)
event_base* base = event_base_new();
//在InterceptManager创建一个event事件
intercept_manager = new InterceptManager(base, intercept_socket);
}
4.2
new InterceptManager(),通过evconnlistener_new创建一个listener,并且设置listener回调为intercept_accept_cb方法,设置this为传入回调方法的自定义参数,设置intercept_socket为传入回调方法的自定义参数
接下来查看intercept_accept_cb回调方法
参数:intercept_socket = android_get_control_socket(kTombstonedInterceptSocketName)
InterceptManager::InterceptManager(event_base* base, int intercept_socket) : base(base) {
this->listener = evconnlistener_new(base, intercept_accept_cb, this, LEV_OPT_CLOSE_ON_FREE,
/* backlog */ -1, intercept_socket);
}
4.3
intercept_accept_cb(),设置了intercept_request_cb方法为intercept_event的回调函数,intercept为传入回调方法的自定义参数
接下来查看intercept_request_cb()
参数:sockfd = android_get_control_socket(kTombstonedInterceptSocketName)
arg = this
static void intercept_accept_cb(evconnlistener* listener, evutil_socket_t sockfd, sockaddr*, int,
void* arg) {
Intercept* intercept = new Intercept();
intercept->intercept_manager = static_cast(arg);
//设置intercept->sockfd = android_get_control_socket(kTombstonedInterceptSocketName)
intercept->sockfd.reset(sockfd);
struct timeval timeout = { 1, 0 };
event_base* base = evconnlistener_get_base(listener);
//通过event_new创建一个event,设置回调函数为intercept_request_cb
event* intercept_event = event_new(base, sockfd, EV_TIMEOUT | EV_READ, intercept_request_cb, intercept);
intercept->intercept_event = intercept_event;
event_add(intercept_event, &timeout);
}
4.4
intercept_request_cb(),
1,这个方法,会接收4.4中创建的管道pipe_write.get(),pid,dump_type等数据,这些数据接下来会用到。
2,会将response回复给android_os_Debug.cpp --->debuggerd_trigger_dump()中的客户端。
所以转回去继续看4.4中提到的debuggerd_trigger_dump()方法,不过将在5中分析剩下的code
参数:sockfd = android_get_control_socket(kTombstonedInterceptSocketName)
arg = 4.3中的intercept
static void intercept_request_cb(evutil_socket_t sockfd, short ev, void* arg) {
//通过arg获取5.3中的intercept
auto intercept = reinterpret_cast(arg);
InterceptManager* intercept_manager = intercept->intercept_manager;
{
unique_fd rcv_fd;
InterceptRequest intercept_request;
//ReceiveFileDescriptors()方法,接收的是4.4中SendFileDescriptors发送的数据
//sockfd = 为socket name = kTombstonedInterceptSocketName 的socket服务端索引(或者可以说是类似文件标识符)
//intercept_request = {.pid = pid, .dump_type = dump_type = "kDebuggerdJavaBacktrace" }
//rcv_fd = pipe_write.get(),即管道写入的指针地址
ssize_t result = ReceiveFileDescriptors(sockfd, &intercept_request, sizeof(intercept_request), &rcv_fd);
//intercept->intercept_pid = pid
intercept->intercept_pid = intercept_request.pid;
//intercept->dump_type = "kDebuggerdJavaBacktrace"
intercept->dump_type = intercept_request.dump_type;
//定义response,response.status = kRegistered
InterceptResponse response = {};
response.status = InterceptStatus::kRegistered;
//通过write方法,将response通过socket回复给sockfd所在的socket客户端,即在4.4中创建的 name = kTombstonedInterceptSocketName 的socket
if (TEMP_FAILURE_RETRY(write(sockfd, &response, sizeof(response))) == -1) {
PLOG(WARNING) << "failed to notify interceptor of registration";
goto fail;
}
//intercept->output_fd = rcv_fd = pipe_write.get()
intercept->output_fd = std::move(rcv_fd);
intercept_manager->intercepts[intercept_request.pid] = std::unique_ptr(intercept);
intercept->registered = true;
//通过event_assign设置回调函数为intercept_close_cb
event_assign(intercept->intercept_event, intercept_manager->base, sockfd, EV_READ | EV_TIMEOUT,
intercept_close_cb, arg);
event_add(intercept->intercept_event, &timeout);
}
}