通过源码搞定ANR Log如何产生(四)

1,302 阅读2分钟

上文中说到,通过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);    
  }  
}