中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

調查android logcat進程退出原因

發布時間:2020-07-17 12:43:51 來源:網絡 閱讀:8892 作者:wuhenaiyan 欄目:移動開發
問題最終的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傳遞給logcat
bool 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;
        }


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

六安市| 镇江市| 左权县| 西乡县| 舞阳县| 营山县| 清徐县| 大悟县| 襄垣县| 南昌县| 双峰县| 昌吉市| 永吉县| 东港市| 江山市| 盘山县| 葫芦岛市| 淄博市| 江北区| 崇仁县| 明溪县| 霸州市| 凤山县| 阿拉尔市| 乐清市| 岑巩县| 邮箱| 萍乡市| 万年县| 美姑县| 海口市| 防城港市| 札达县| 司法| 区。| 宝坻区| 博客| 阜城县| 嘉义市| 皋兰县| 英吉沙县|