appNotResponding()分析

來源:互聯網
上載者:User

標籤:

ActivityManagerService.appNotResponding()在程式無響應、ANR時被調用,分析這個函數有有助於更好地理解日誌中列印出的資訊。

    final void appNotResponding(ProcessRecord app, ActivityRecord activity,            ActivityRecord parent, boolean aboveSystem, final String annotation) {        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);        if (mController != null) {            try {                // 0 == continue, -1 = kill process immediately                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);            } catch (RemoteException e) {                mController = null;                Watchdog.getInstance().setActivityController(null);            }        }        long anrTime = SystemClock.uptimeMillis();        if (MONITOR_CPU_USAGE) {            updateCpuStatsNow();        }        synchronized (this) {            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.            if (mShuttingDown) {                                                    //如果系統正在關機,ANR不處理,return;                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);                return;            } else if (app.notResponding) {                                         //如果之前已經報過該進程ANR了,那麼不再執行下面的邏輯,直接列印“<span style="font-family: Arial, Helvetica, sans-serif;">Skipping duplicate ANR“,然後return;</span>”                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);                return;            } else if (app.crashing) {                                              //如果應用發生crash,此時ANR忽略掉,return;                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);                return;            }            // In case we come through here for the same app before completing            // this one, mark as anring now so we will bail out.            app.notResponding = true;                                            //將<span style="font-family: Arial, Helvetica, sans-serif;">notResponding 設為true,表示已經在處理該進程的ANR,下次再報ANR直接return;</span>            // Log the ANR to the event log.                                   EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,        //往event日誌中寫AM_ANR資訊,全域搜尋了下,只有這一個地方列印event ANR日誌,那麼如果event日誌中有此日誌項,就說明已經走進這個函數邏輯裡面了;                    app.processName, app.info.flags, annotation);            // Dump thread traces as quickly as we can, starting with "interesting" processes.            firstPids.add(app.pid);                                              //將出ANR的進程加入<span style="font-family: Arial, Helvetica, sans-serif;">firstPids列表,後續列印該進程的trace;</span>            int parentPid = app.pid;            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;       //將父進程也加入<span style="font-family: Arial, Helvetica, sans-serif;">firstPids列表;</span>            if (parentPid != app.pid) firstPids.add(parentPid);            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);             //將system_server進程加入<span style="font-family: Arial, Helvetica, sans-serif;">firstPids列表,說明每次ANR的trace中必然包括system_server進程的trace;</span>            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {                ProcessRecord r = mLruProcesses.get(i);                if (r != null && r.thread != null) {                    int pid = r.pid;                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {                        if (r.persistent) {                            firstPids.add(pid);                                      //將常駐進程也加入<span style="font-family: Arial, Helvetica, sans-serif;">firstPids列表中;</span>                        } else {                            lastPids.put(pid, Boolean.TRUE);                        }                    }                }            }        }        // Log the ANR to the main log.        StringBuilder info = new StringBuilder();        info.setLength(0);        info.append("ANR in ").append(app.processName);                  //"ANR in"也是分析ANR的關鍵日誌;        if (activity != null && activity.shortComponentName != null) {            info.append(" (").append(activity.shortComponentName).append(")");        }        info.append("\n");        info.append("PID: ").append(app.pid).append("\n");        if (annotation != null) {            info.append("Reason: ").append(annotation).append("\n");        }        if (parent != null && parent != activity) {            info.append("Parent: ").append(parent.shortComponentName).append("\n");        }        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,                NATIVE_STACKS_OF_INTEREST);        String cpuInfo = null;        if (MONITOR_CPU_USAGE) {            updateCpuStatsNow();            synchronized (mProcessCpuThread) {                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);            }            info.append(processCpuTracker.printCurrentLoad());            info.append(cpuInfo);        }        info.append(processCpuTracker.printCurrentState(anrTime));        Slog.e(TAG, info.toString());        if (tracesFile == null) {                                 //如果調用<span style="font-family: Arial, Helvetica, sans-serif;">dumpStackTraces沒有生存trace,那麼重新只列印ANR進程trace;</span>            // There is no trace file, so dump (only) the alleged culprit's threads to the log            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);        }        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,           //將trace檔案加入DropBox中,這麼說來只要發生ANR,並在日誌中有"ANR in",那麼在DropBox中必然有一份trace日誌,命名已‘ANR’形式;                cpuInfo, tracesFile, null);        if (mController != null) {            try {                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately                int res = mController.appNotResponding(app.processName, app.pid, info.toString());                if (res != 0) {                    if (res < 0 && app.pid != MY_PID) {                        Process.killProcess(app.pid);                    } else {                        synchronized (this) {                            mServices.scheduleServiceTimeoutLocked(app);                        }                    }                    return;                }            } catch (RemoteException e) {                mController = null;                Watchdog.getInstance().setActivityController(null);            }        }        // Unless configured otherwise, swallow ANRs in background processes & kill the process.        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;        synchronized (this) {            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {                killUnneededProcessLocked(app, "background ANR");                return;            }            // Set the app's notResponding state, and look up the errorReportReceiver            makeAppNotRespondingLocked(app,                    activity != null ? activity.shortComponentName : null,                    annotation != null ? "ANR " + annotation : "ANR",                    info.toString());            // Bring up the infamous App Not Responding dialog            Message msg = Message.obtain();            HashMap<String, Object> map = new HashMap<String, Object>();            msg.what = SHOW_NOT_RESPONDING_MSG;            msg.obj = map;            msg.arg1 = aboveSystem ? 1 : 0;            map.put("app", app);            if (activity != null) {                map.put("activity", activity);            }            mHandler.sendMessage(msg);        }    }



appNotResponding()分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.