问题最终的logcat进程退出的原因是logbuffersize设置过小导致,默认size为256KB,将buffersize设置为4MB后,后面就再没有出现过logcat中断的情况;修改的code就一行代码,但这个原因的调查过程确实不易,这里记录一二1、测试同事在android8.0平台版本中经常遇到logcat进程中途退出的情况,导致抓的logcat信息不全,给分析定位问题带来不便;2、基于出现的这种,进行分析logcat进程退出的可能性;一,在logcat进程中断时,监听logcat进程的程序显示exitcode[1];有时候在cmd终端窗口显示"unexpectedEOF",查看logcat.cpp相关code,看到是logcat进程的while循环中android_logger_list_read读取到的数据为0,logcat进程主动调用logcat_panic进程,logcat进程退出。二,然后尝试跟踪logcat进程读取数据的code流程,最终发现关联的内容蛮多的,有liblog、libsysutils、logd,主要是这三个模块;分析这类问题的最大难点是logcat进程退出时,是没有相关logcat信息的,很难看到问题原因,只能自己dup重定向标准输入输出或者将log打印kmsg模块中;最终根据添加的调试信息和打印log确认与buffersize有关;分析大致过程如下:1、在应用或者服务等进程往logd中写入log量过大时(大于buffersize设置的2倍),logd会调用kickMe函数,这里面会去判断statssize即系统中实际需要占用的大小,当大于2倍我们在init函数中设定的默认buffersize(64KB)时,Logd认为reader读取数据的速度过慢,会主动release_Locked函数尝试断开连接,断开连接后会导致logd.reader.per线程while循环break退出;Logd.cpp->kickMe函数部分代码:voidLogBuffer::kickMe(LogTimeEntry*me,log_id_tid,unsignedlongpruneRows){if(stats.sizes(id)>(2*log_buffer_size(id))){//+100%//Amisbehavingorslowreaderhasitsconnection//droppedifwehittoomuchmemorypressure.me->release_Locked();2、logd.reader.per线程线程退出后,会调用SocketListener监听类的SocketListener::release,logd开启的LogReader是继承自SocketListener,会调用到doSocketDelete,SocketClient相关联的decRef函数,mRefCount—减值后会调用到~SocketClient析构函数,析构后会调用close(mSocket)关闭SocketListener端的socket连接,3、socketListener的socket连接端开后,LogReader中onDataAvailable中read函数读取不到数据,返回值为0,LogReader是将log传递给logcatboolLogReader::onDataAvailable(SocketClient*cli){staticboolname_set;if(!name_set){prctl(PR_SET_NAME,"logd.reader");name_set=true;}charbuffer[255];intlen=read(cli->getSocket(),buffer,sizeof(buffer)-1);if(len<=0){android::prdebug("LogReader->onDataAvailable,length:%d!\n",len);doSocketDelete(cli);returnfalse;}4、接着会导致liblog模块的logdRead的recv函数返回值ret为0(省略一部分transport相关过程,里面还有一些转化步骤),staticintlogdRead(structandroid_log_logger_list*logger_list,ret=recv(ret,log_msg,LOGGER_ENTRY_MAX_LEN,0);e=errno;fprintf(stderr,"logdRead()->receiveret:%d^^^^^^^^^^^\n",ret);5、导致最终Logcat端进程的while循环中android_logger_list_read读取到的数据为0,logcat进程主动调用logcat_panic进程,logcat进程退出。while(!context->stop&&(!context->maxCount||(context->printCount<context->maxCount))){structlog_msglog_msg;intret=android_logger_list_read(logger_list,&log_msg);if(!ret){fprintf(stderr,"android_logger_list_readerror,ret:%d!\n",ret);logcat_panic(context,HELP_FALSE,"read:unexpectedEOF!\n");break;}