Android system server之WatchDog看门狗分析
生活随笔
收集整理的這篇文章主要介紹了
Android system server之WatchDog看门狗分析
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
android -- WatchDog看門狗分析
在由單片機(jī)構(gòu)成的微型計算機(jī)系統(tǒng)中,由于單片機(jī)的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環(huán),程序的正常運行被打斷,由單片機(jī)控制的系統(tǒng)無法繼續(xù)工作,會造成整個系統(tǒng)的陷入停滯狀態(tài),發(fā)生不可預(yù)料的后果,所以出于對單片機(jī)運行狀態(tài)進(jìn)行實時監(jiān)測的考慮,便產(chǎn)生了一種專門用于監(jiān)測單片機(jī)程序運行狀態(tài)的芯片,俗稱"看門狗"。
在Android系統(tǒng)中也需要看好幾個重要的Service門,用于發(fā)現(xiàn)出了問題的Service殺掉SystemServer進(jìn)程,所以有必要了解并分析其系統(tǒng)問題。
那么被監(jiān)控的有哪些Service呢?
ActivityManagerService.java :frameworks\base\services\java\com\android\server\am
PowerManagerService.java ? ?:frameworks\base\services\java\com\android\server
WindowManagerService.java ? :frameworks\base\services\java\com\android\server
下面就依次分析一下其整個處理流程:
1、初始化
run @ SysemServer.java
?? ? ?Slog.i(TAG, "Init Watchdog");
?? ? ?Watchdog.getInstance().init(context, battery, power, alarm,
?? ? ? ? ? ? ?ActivityManagerService.self());
這里使用單例模式創(chuàng)建:
?? ?public static Watchdog getInstance() {
?? ? ? ?if (sWatchdog == null) {
?? ? ? ? ? ?sWatchdog = new Watchdog();
?? ? ? ?}
?? ? ? ?return sWatchdog;
?? ?}
?? ?public void init(Context context, BatteryService battery,
?? ? ? ? ? ?PowerManagerService power, AlarmManagerService alarm,
?? ? ? ? ? ?ActivityManagerService activity) {
?? ? ? ?// 上下文環(huán)境變量
?? ? ? ?mResolver = context.getContentResolver();
?? ? ? ?mBattery = battery;
?? ? ? ?mPower = power;
?? ? ? ?mAlarm = alarm;
?? ? ? ?mActivity = activity;
// 登記 RebootReceiver() 接收,用于reboot廣播接收使用 ?? ? ? ?context.registerReceiver(new RebootReceiver(),
?? ?}
ok,調(diào)用init函數(shù)啟動完畢
2、運行中
run @ SysemServer.java
調(diào)用 Watchdog.getInstance().start(); 啟動看門狗
首先看下 Watchdog 類定義:
/** This class calls its monitor every minute. Killing this process if they don't return **/
public class Watchdog extends Thread {
}
從線程類中繼承,即會在一個單獨線程中運行,調(diào)用thrrad.start()即調(diào)用 Watchdog.java 中的 run() 函數(shù)
?? ?public void run() {
?? ? ? ?boolean waitedHalf = false;
?? ? ? ?while (true) {
?? ? ? ? ? ?mCompleted = false;
?? ? ? ? ? ?
?? ? ? ? ? ?// 1、給mHandler發(fā)送 MONITOR 消息,用于請求檢查 Service是否工作正常
?? ? ? ? ? ?mHandler.sendEmptyMessage(MONITOR);
?? ? ? ? ? ?synchronized (this) {
// 2、進(jìn)行 wait 等待 timeout 時間確認(rèn)是否退出循環(huán) ? ? ? ? ? ? ?? ? ? ? ? ? ? ?long timeout = TIME_TO_WAIT; ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ?// NOTE: We use uptimeMillis() here because we do not want to increment the time we
?? ? ? ? ? ? ? ?// wait while asleep. If the device is asleep then the thing that we are waiting
?? ? ? ? ? ? ? ?// to timeout on is asleep as well and won't have a chance to run, causing a false
?? ? ? ? ? ? ? ?// positive on when to kill things.
?? ? ? ? ? ? ? ?long start = SystemClock.uptimeMillis();
?? ? ? ? ? ? ? ?while (timeout > 0 && !mForceKillSystem) {
?? ? ? ? ? ? ? ? ? ?try {
?? ? ? ? ? ? ? ? ? ? ? ?wait(timeout); ?// notifyAll() is called when mForceKillSystem is set
?? ? ? ? ? ? ? ? ? ?} catch (InterruptedException e) {
?? ? ? ? ? ? ? ? ? ? ? ?Log.wtf(TAG, e);
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ? ? ?timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start);
?? ? ? ? ? ? ? ?}
// 3、如果 mCompleted 為真表示service一切正常,后面會再講到 ?? ? ? ? ? ? ? ?if (mCompleted && !mForceKillSystem) {
?? ? ? ? ? ? ? ? ? ?// The monitors have returned.
?? ? ? ? ? ? ? ? ? ?waitedHalf = false;
?? ? ? ? ? ? ? ? ? ?continue;
?? ? ? ? ? ? ? ?}
// 4、表明檢測到了有 deadlock-detection 條件發(fā)生,利用 dumpStackTraces 打印堆棧依信息 ?? ? ? ? ? ? ? ?if (!waitedHalf) {
?? ? ? ? ? ? ? ? ? ?// We've waited half the deadlock-detection interval. ?Pull a stack
?? ? ? ? ? ? ? ? ? ?// trace and wait another half.
?? ? ? ? ? ? ? ? ? ?ArrayList<Integer> pids = new ArrayList<Integer>();
?? ? ? ? ? ? ? ? ? ?pids.add(Process.myPid());
?? ? ? ? ? ? ? ? ? ?ActivityManagerService.dumpStackTraces(true, pids, null, null);
?? ? ? ? ? ? ? ? ? ?waitedHalf = true;
?? ? ? ? ? ? ? ? ? ?continue; // 不過這里會再次檢測一次
?? ? ? ? ? ? ? ?}
}
SystemClock.sleep(2000);
?? ? ? ? ? ?
?? ? ? ? ? ?// 5、打印內(nèi)核棧調(diào)用關(guān)系
?? ? ? ? ? ?// Pull our own kernel thread stacks as well if we're configured for that
?? ? ? ? ? ?if (RECORD_KERNEL_THREADS) {
?? ? ? ? ? ? ? ?dumpKernelStackTraces();
?? ? ? ? ? ?}
// 6、ok,系統(tǒng)出問題了,檢測到某個 Service 出現(xiàn)死鎖情況,殺死SystemServer進(jìn)程 ?? ? ? ? ? ?// Only kill the process if the debugger is not attached.
?? ? ? ? ? ?if (!Debug.isDebuggerConnected()) {
?? ? ? ? ? ? ? ?Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
?? ? ? ? ? ? ? ?Process.killProcess(Process.myPid());
?? ? ? ? ? ? ? ?System.exit(10);
?? ? ? ? ? ?} else {
?? ? ? ? ? ? ? ?Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
?? ? ? ? ? ?}
?? ? ? ? ? ?waitedHalf = false;
?? ? ? ?}
?? ?}
主要工作邏輯:監(jiān)控線程每隔一段時間發(fā)送一條 MONITOR 線另外一個線程,另個一個線程會檢查各個 Service 是否正常運行,看門狗就不停的檢查并等待結(jié)果,失敗則殺死SystemServer.
3、Service 檢查線程
?? ?/**
?? ? * Used for scheduling monitor callbacks and checking memory usage.
?? ? */
?? ?final class HeartbeatHandler extends Handler {
@Override
?? ?public void handleMessage(Message msg) { ?// Looper 消息處理函數(shù)
?? ? ? ? ? ?switch (msg.what) {
?? ? ? ? ? ?
?? ? ? ? ? ? ? ?case MONITOR: {
?? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor = mMonitors.get(i);
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor.monitor();
?? ? ? ? ? ? ? ? ? ?}
// 檢測成功則設(shè)置 mCompleted 變量為 true ?? ? ? ? ? ? ? ? ? ?synchronized (Watchdog.this) {
?? ? ? ? ? ? ? ? ? ? ? ?mCompleted = true;
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor = null;
?? ? ? ? ? ? ? ? ? ?}
下面我們來看一下各個Service如何確定自已運行ok呢?以 ActivityManagerService 為例:
首先加入檢查隊列:
private ActivityManagerService() {
?? ? ? ?// Add ourself to the Watchdog monitors.
?? ? ? ?Watchdog.getInstance().addMonitor(this);
}
然后實現(xiàn) monitor() 函數(shù):
?? ?/** In this method we try to acquire our lock to make sure that we have not deadlocked */
?? ?public void monitor() {
?? ? ? ?synchronized (this) { }
?? ?}
明白了吧,其實就是檢查這個 Service 是否發(fā)生了死鎖,對于此情況就只能kill SystemServer系統(tǒng)了。對于死鎖的產(chǎn)生原因非常多,但有個情況需要注意:java層死鎖可能發(fā)生在調(diào)用native函數(shù),而native函數(shù)可能與硬件交互導(dǎo)致時間過長而沒有返回,從而導(dǎo)致長時間占用導(dǎo)致問題。
4、內(nèi)存使用檢測
消息發(fā)送 final class GlobalPssCollected implements Runnable { ?? ? ? ?public void run() {
?? ? ? ? ? ?mHandler.sendEmptyMessage(GLOBAL_PSS);
?? ? ? ?}
?? ?}
?? ?
?? ?檢測內(nèi)存處理函數(shù):
?? ?final class HeartbeatHandler extends Handler {
?? ? ? ?@Override
?? ? ? ?public void handleMessage(Message msg) {
?? ? ? ? ? ?switch (msg.what) {
?? ? ? ? ? ? ? ?case GLOBAL_PSS: {
?? ? ? ? ? ? ? ? ? ?if (mHaveGlobalPss) {
?? ? ? ? ? ? ? ? ? ? ? ?// During the last pass we collected pss information, so
?? ? ? ? ? ? ? ? ? ? ? ?// now it is time to report it.
?? ? ? ? ? ? ? ? ? ? ? ?mHaveGlobalPss = false;
?? ? ? ? ? ? ? ? ? ? ? ?if (localLOGV) Slog.v(TAG, "Received global pss, logging.");
?? ? ? ? ? ? ? ? ? ? ? ?logGlobalMemory(); ?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?} break;
?? ? ? ? ? ? ? ?
?? ? ? ?
?? ? ? ?其主要功能如下,統(tǒng)計pSS狀況及讀取相關(guān)linux內(nèi)核中內(nèi)存信息:
?? ? ? ?void logGlobalMemory() { ? ? ? ?
?? ? ? ?mActivity.collectPss(stats);
?? ? ? ?
?? ? ? ?Process.readProcLines("/proc/meminfo", mMemInfoFields, mMemInfoSizes);
?? ? ? ?
?? ? ? ?Process.readProcLines("/proc/vmstat", mVMStatFields, mVMStatSizes); ? ? ? ?
在由單片機(jī)構(gòu)成的微型計算機(jī)系統(tǒng)中,由于單片機(jī)的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環(huán),程序的正常運行被打斷,由單片機(jī)控制的系統(tǒng)無法繼續(xù)工作,會造成整個系統(tǒng)的陷入停滯狀態(tài),發(fā)生不可預(yù)料的后果,所以出于對單片機(jī)運行狀態(tài)進(jìn)行實時監(jiān)測的考慮,便產(chǎn)生了一種專門用于監(jiān)測單片機(jī)程序運行狀態(tài)的芯片,俗稱"看門狗"。
在Android系統(tǒng)中也需要看好幾個重要的Service門,用于發(fā)現(xiàn)出了問題的Service殺掉SystemServer進(jìn)程,所以有必要了解并分析其系統(tǒng)問題。
那么被監(jiān)控的有哪些Service呢?
ActivityManagerService.java :frameworks\base\services\java\com\android\server\am
PowerManagerService.java ? ?:frameworks\base\services\java\com\android\server
WindowManagerService.java ? :frameworks\base\services\java\com\android\server
下面就依次分析一下其整個處理流程:
1、初始化
run @ SysemServer.java
?? ? ?Slog.i(TAG, "Init Watchdog");
?? ? ?Watchdog.getInstance().init(context, battery, power, alarm,
?? ? ? ? ? ? ?ActivityManagerService.self());
這里使用單例模式創(chuàng)建:
?? ?public static Watchdog getInstance() {
?? ? ? ?if (sWatchdog == null) {
?? ? ? ? ? ?sWatchdog = new Watchdog();
?? ? ? ?}
?? ? ? ?return sWatchdog;
?? ?}
?? ?public void init(Context context, BatteryService battery,
?? ? ? ? ? ?PowerManagerService power, AlarmManagerService alarm,
?? ? ? ? ? ?ActivityManagerService activity) {
?? ? ? ?// 上下文環(huán)境變量
?? ? ? ?mResolver = context.getContentResolver();
?? ? ? ?mBattery = battery;
?? ? ? ?mPower = power;
?? ? ? ?mAlarm = alarm;
?? ? ? ?mActivity = activity;
// 登記 RebootReceiver() 接收,用于reboot廣播接收使用 ?? ? ? ?context.registerReceiver(new RebootReceiver(),
?? ? ? ? ? ? ? ?new IntentFilter(REBOOT_ACTION));
?? ?}
ok,調(diào)用init函數(shù)啟動完畢
2、運行中
run @ SysemServer.java
調(diào)用 Watchdog.getInstance().start(); 啟動看門狗
首先看下 Watchdog 類定義:
/** This class calls its monitor every minute. Killing this process if they don't return **/
public class Watchdog extends Thread {
}
從線程類中繼承,即會在一個單獨線程中運行,調(diào)用thrrad.start()即調(diào)用 Watchdog.java 中的 run() 函數(shù)
?? ?public void run() {
?? ? ? ?boolean waitedHalf = false;
?? ? ? ?while (true) {
?? ? ? ? ? ?mCompleted = false;
?? ? ? ? ? ?
?? ? ? ? ? ?// 1、給mHandler發(fā)送 MONITOR 消息,用于請求檢查 Service是否工作正常
?? ? ? ? ? ?mHandler.sendEmptyMessage(MONITOR);
?? ? ? ? ? ?synchronized (this) {
// 2、進(jìn)行 wait 等待 timeout 時間確認(rèn)是否退出循環(huán) ? ? ? ? ? ? ?? ? ? ? ? ? ? ?long timeout = TIME_TO_WAIT; ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ?// NOTE: We use uptimeMillis() here because we do not want to increment the time we
?? ? ? ? ? ? ? ?// wait while asleep. If the device is asleep then the thing that we are waiting
?? ? ? ? ? ? ? ?// to timeout on is asleep as well and won't have a chance to run, causing a false
?? ? ? ? ? ? ? ?// positive on when to kill things.
?? ? ? ? ? ? ? ?long start = SystemClock.uptimeMillis();
?? ? ? ? ? ? ? ?while (timeout > 0 && !mForceKillSystem) {
?? ? ? ? ? ? ? ? ? ?try {
?? ? ? ? ? ? ? ? ? ? ? ?wait(timeout); ?// notifyAll() is called when mForceKillSystem is set
?? ? ? ? ? ? ? ? ? ?} catch (InterruptedException e) {
?? ? ? ? ? ? ? ? ? ? ? ?Log.wtf(TAG, e);
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ? ? ?timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start);
?? ? ? ? ? ? ? ?}
// 3、如果 mCompleted 為真表示service一切正常,后面會再講到 ?? ? ? ? ? ? ? ?if (mCompleted && !mForceKillSystem) {
?? ? ? ? ? ? ? ? ? ?// The monitors have returned.
?? ? ? ? ? ? ? ? ? ?waitedHalf = false;
?? ? ? ? ? ? ? ? ? ?continue;
?? ? ? ? ? ? ? ?}
// 4、表明檢測到了有 deadlock-detection 條件發(fā)生,利用 dumpStackTraces 打印堆棧依信息 ?? ? ? ? ? ? ? ?if (!waitedHalf) {
?? ? ? ? ? ? ? ? ? ?// We've waited half the deadlock-detection interval. ?Pull a stack
?? ? ? ? ? ? ? ? ? ?// trace and wait another half.
?? ? ? ? ? ? ? ? ? ?ArrayList<Integer> pids = new ArrayList<Integer>();
?? ? ? ? ? ? ? ? ? ?pids.add(Process.myPid());
?? ? ? ? ? ? ? ? ? ?ActivityManagerService.dumpStackTraces(true, pids, null, null);
?? ? ? ? ? ? ? ? ? ?waitedHalf = true;
?? ? ? ? ? ? ? ? ? ?continue; // 不過這里會再次檢測一次
?? ? ? ? ? ? ? ?}
}
SystemClock.sleep(2000);
?? ? ? ? ? ?
?? ? ? ? ? ?// 5、打印內(nèi)核棧調(diào)用關(guān)系
?? ? ? ? ? ?// Pull our own kernel thread stacks as well if we're configured for that
?? ? ? ? ? ?if (RECORD_KERNEL_THREADS) {
?? ? ? ? ? ? ? ?dumpKernelStackTraces();
?? ? ? ? ? ?}
// 6、ok,系統(tǒng)出問題了,檢測到某個 Service 出現(xiàn)死鎖情況,殺死SystemServer進(jìn)程 ?? ? ? ? ? ?// Only kill the process if the debugger is not attached.
?? ? ? ? ? ?if (!Debug.isDebuggerConnected()) {
?? ? ? ? ? ? ? ?Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
?? ? ? ? ? ? ? ?Process.killProcess(Process.myPid());
?? ? ? ? ? ? ? ?System.exit(10);
?? ? ? ? ? ?} else {
?? ? ? ? ? ? ? ?Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
?? ? ? ? ? ?}
?? ? ? ? ? ?waitedHalf = false;
?? ? ? ?}
?? ?}
主要工作邏輯:監(jiān)控線程每隔一段時間發(fā)送一條 MONITOR 線另外一個線程,另個一個線程會檢查各個 Service 是否正常運行,看門狗就不停的檢查并等待結(jié)果,失敗則殺死SystemServer.
3、Service 檢查線程
?? ?/**
?? ? * Used for scheduling monitor callbacks and checking memory usage.
?? ? */
?? ?final class HeartbeatHandler extends Handler {
@Override
?? ?public void handleMessage(Message msg) { ?// Looper 消息處理函數(shù)
?? ? ? ? ? ?switch (msg.what) {
?? ? ? ? ? ?
?? ? ? ? ? ? ? ?case MONITOR: {
?? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ?// 依次檢測各個服務(wù),即調(diào)用 monitor() 函數(shù)
?? ? ? ? ? ? ? ? ? ?final int size = mMonitors.size();
?? ? ? ? ? ? ? ? ? ?for (int i = 0 ; i < size ; i++) {?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor = mMonitors.get(i);
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor.monitor();
?? ? ? ? ? ? ? ? ? ?}
// 檢測成功則設(shè)置 mCompleted 變量為 true ?? ? ? ? ? ? ? ? ? ?synchronized (Watchdog.this) {
?? ? ? ? ? ? ? ? ? ? ? ?mCompleted = true;
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor = null;
?? ? ? ? ? ? ? ? ? ?}
下面我們來看一下各個Service如何確定自已運行ok呢?以 ActivityManagerService 為例:
首先加入檢查隊列:
private ActivityManagerService() {
?? ? ? ?// Add ourself to the Watchdog monitors.
?? ? ? ?Watchdog.getInstance().addMonitor(this);
}
然后實現(xiàn) monitor() 函數(shù):
?? ?/** In this method we try to acquire our lock to make sure that we have not deadlocked */
?? ?public void monitor() {
?? ? ? ?synchronized (this) { }
?? ?}
明白了吧,其實就是檢查這個 Service 是否發(fā)生了死鎖,對于此情況就只能kill SystemServer系統(tǒng)了。對于死鎖的產(chǎn)生原因非常多,但有個情況需要注意:java層死鎖可能發(fā)生在調(diào)用native函數(shù),而native函數(shù)可能與硬件交互導(dǎo)致時間過長而沒有返回,從而導(dǎo)致長時間占用導(dǎo)致問題。
4、內(nèi)存使用檢測
消息發(fā)送 final class GlobalPssCollected implements Runnable { ?? ? ? ?public void run() {
?? ? ? ? ? ?mHandler.sendEmptyMessage(GLOBAL_PSS);
?? ? ? ?}
?? ?}
?? ?
?? ?檢測內(nèi)存處理函數(shù):
?? ?final class HeartbeatHandler extends Handler {
?? ? ? ?@Override
?? ? ? ?public void handleMessage(Message msg) {
?? ? ? ? ? ?switch (msg.what) {
?? ? ? ? ? ? ? ?case GLOBAL_PSS: {
?? ? ? ? ? ? ? ? ? ?if (mHaveGlobalPss) {
?? ? ? ? ? ? ? ? ? ? ? ?// During the last pass we collected pss information, so
?? ? ? ? ? ? ? ? ? ? ? ?// now it is time to report it.
?? ? ? ? ? ? ? ? ? ? ? ?mHaveGlobalPss = false;
?? ? ? ? ? ? ? ? ? ? ? ?if (localLOGV) Slog.v(TAG, "Received global pss, logging.");
?? ? ? ? ? ? ? ? ? ? ? ?logGlobalMemory(); ?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?} break;
?? ? ? ? ? ? ? ?
?? ? ? ?
?? ? ? ?其主要功能如下,統(tǒng)計pSS狀況及讀取相關(guān)linux內(nèi)核中內(nèi)存信息:
?? ? ? ?void logGlobalMemory() { ? ? ? ?
?? ? ? ?mActivity.collectPss(stats);
?? ? ? ?
?? ? ? ?Process.readProcLines("/proc/meminfo", mMemInfoFields, mMemInfoSizes);
?? ? ? ?
?? ? ? ?Process.readProcLines("/proc/vmstat", mVMStatFields, mVMStatSizes); ? ? ? ?
?? ? ? ?}
原文:http://blog.csdn.net/andyhuabing/article/details/7395391
總結(jié)
以上是生活随笔為你收集整理的Android system server之WatchDog看门狗分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拷贝的Android源码不能单独编译mm
- 下一篇: Android system serve