調查android logcat進程退出原因

來源:互聯網
上載者:User

標籤:sock   sig   ase   最大   soc   開啟   標準   listen   stat   

問題最終的logcat進程退出的原因是log buffer size設定過小導致,預設size為256KB,將buffer size設定為4MB後,後面就再沒有出現過logcat中斷的情況;修改的code就一行代碼,但這個原因的調查過程確實不易,這裡記錄一二1、測試同事在android 8.0平台版本中經常遇到logcat進程中途退出的情況,導致抓的logcat資訊不全,給分析定位問題帶來不便;2、基於出現的這種,進行分析logcat進程退出的可能性; 一,在logcat進程中斷時,監聽logcat進程的程式顯示exit code[1];   有時候在cmd終端視窗顯示"unexpected EOF",查看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確認與buffer size有關;       分析大致過程如下:1、  在應用或者服務等進程 往logd中寫入log量過大時(大於buffer size設定的2倍),logd會調用kickMe函數,這裡面會去判斷stats size即系統中實際需要佔用的大小,當大於2倍我們在init函數中設定的預設buffer size(64KB)時,Logd認為reader讀取資料的速度過慢,會主動release_Locked函數嘗試中斷連線,中斷連線後會導致logd.reader.per線程while迴圈break退出;Logd.cpp -> kickMe函數部分代碼:void LogBuffer::kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows) {    if (stats.sizes(id) > (2 * log_buffer_size(id))) {  // +100%        // A misbehaving or slow reader has its connection        // dropped if we hit too much memory pressure.        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傳遞給logcatbool LogReader::onDataAvailable(SocketClient* cli) {    static bool name_set;    if (!name_set) {        prctl(PR_SET_NAME, "logd.reader");        name_set = true;    }     char buffer[255];     int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1);    if (len <= 0) {         android::prdebug("LogReader->onDataAvailable ,length:%d !\n", len);        doSocketDelete(cli);        return false;    } 4、接著會導致liblog模組的logdRead的recv函數傳回值ret為0(省略一部分transport相關過程,裡面還有一些轉化步驟),static int logdRead(struct android_log_logger_list* logger_list,  ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);  e = errno;  fprintf(stderr, "logdRead()-> receive  ret :%d  ^^^^^^^^^^^\n",ret);  5、導致最終Logcat端進程的while迴圈中android_logger_list_read讀取到的資料為0,logcat進程主動調用logcat_panic進程,logcat進程退出。    while (!context->stop &&           (!context->maxCount || (context->printCount < context->maxCount))) {        struct log_msg log_msg;        int ret = android_logger_list_read(logger_list, &log_msg);        if (!ret) {              fprintf(stderr, "android_logger_list_read error ,ret:%d !\n", ret);            logcat_panic(context, HELP_FALSE, "read: unexpected EOF!\n");            break;        }


調查android logcat進程退出原因

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.