第十板块:Android 系统稳定性与调试 | 第二十五篇:Watchdog 与 ANR 的系统级监控

第十板块:Android 系统稳定性与调试 | 第二十五篇:Watchdog 与 ANR 的系统级监控

所属板块:第十板块 --- Android 系统稳定性与调试

前置知识:第九板块中的多媒体架构(Camera/HAL3/AudioFlinger)、System Server 内部机制、Binder IPC 线程模型、Linux 信号机制(SIGQUIT)

本篇定位 :这是 Android 系统自我诊断与自我修复的最后一道防线 。如果说前面的组件是器官,那么 Watchdog 就是免疫系统 。本篇将彻底拆解 System Server Watchdog 的监测模型、ANR(Application Not Responding) 的触发与检测机制、Monitor 接口 的心跳检测、Native CrashJava Crash 的区别、Tombstone 的生成与分析。我们将深入 Watchdog 线程ActivityManagerService 的 ANR 逻辑Signal Catcher 线程,揭示 Android 如何在系统即将死锁或应用无响应时,优雅地收集证据并重启。全程无抓 Crash 技巧、无 ANR 排查指南,仅保留 Android 稳定性系统的底层定义与监控规范。


1. 核心结论先行(Thesis Statement)

Android 的稳定性监控是一个基于超时与死锁检测的双重保险系统

  • Watchdog 的本质系统服务的心跳监护仪 。它运行在 System Server 的独立线程中,定期向关键系统服务(AMS, WMS, PMS 等)发送 Monitor 检查 。如果服务在规定时间内没有响应,Watchdog 判定系统死锁,触发 Kernel PanicSystem Server 重启
  • ANR 的本质应用主线程的超时陷阱 。当应用主线程在特定操作(Input, Broadcast, Service)上阻塞超过阈值(5秒/10秒/60秒),ActivityManagerService 判定应用无响应,弹出 ANR 对话框并生成 /data/anr/traces.txt
  • Monitor 的本质死锁探测接口 。系统服务实现 Watchdog.Monitor 接口,在 monitor() 方法中尝试获取关键锁。如果获取不到,说明发生了死锁。
  • Tombstone 的本质进程临终快照。当 Native 层发生严重错误(段错误、非法指令)时,系统生成一份包含寄存器、堆栈、内存映射的二进制墓碑文件。

2. 稳定性监控全景图

2.1 系统级监控架构

#mermaid-svg-aY0K5Garg6pnA34x{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aY0K5Garg6pnA34x .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aY0K5Garg6pnA34x .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aY0K5Garg6pnA34x .error-icon{fill:#552222;}#mermaid-svg-aY0K5Garg6pnA34x .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aY0K5Garg6pnA34x .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aY0K5Garg6pnA34x .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aY0K5Garg6pnA34x .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aY0K5Garg6pnA34x .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aY0K5Garg6pnA34x .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aY0K5Garg6pnA34x .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aY0K5Garg6pnA34x .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aY0K5Garg6pnA34x .marker.cross{stroke:#333333;}#mermaid-svg-aY0K5Garg6pnA34x svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aY0K5Garg6pnA34x p{margin:0;}#mermaid-svg-aY0K5Garg6pnA34x .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aY0K5Garg6pnA34x .cluster-label text{fill:#333;}#mermaid-svg-aY0K5Garg6pnA34x .cluster-label span{color:#333;}#mermaid-svg-aY0K5Garg6pnA34x .cluster-label span p{background-color:transparent;}#mermaid-svg-aY0K5Garg6pnA34x .label text,#mermaid-svg-aY0K5Garg6pnA34x span{fill:#333;color:#333;}#mermaid-svg-aY0K5Garg6pnA34x .node rect,#mermaid-svg-aY0K5Garg6pnA34x .node circle,#mermaid-svg-aY0K5Garg6pnA34x .node ellipse,#mermaid-svg-aY0K5Garg6pnA34x .node polygon,#mermaid-svg-aY0K5Garg6pnA34x .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aY0K5Garg6pnA34x .rough-node .label text,#mermaid-svg-aY0K5Garg6pnA34x .node .label text,#mermaid-svg-aY0K5Garg6pnA34x .image-shape .label,#mermaid-svg-aY0K5Garg6pnA34x .icon-shape .label{text-anchor:middle;}#mermaid-svg-aY0K5Garg6pnA34x .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aY0K5Garg6pnA34x .rough-node .label,#mermaid-svg-aY0K5Garg6pnA34x .node .label,#mermaid-svg-aY0K5Garg6pnA34x .image-shape .label,#mermaid-svg-aY0K5Garg6pnA34x .icon-shape .label{text-align:center;}#mermaid-svg-aY0K5Garg6pnA34x .node.clickable{cursor:pointer;}#mermaid-svg-aY0K5Garg6pnA34x .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aY0K5Garg6pnA34x .arrowheadPath{fill:#333333;}#mermaid-svg-aY0K5Garg6pnA34x .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aY0K5Garg6pnA34x .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aY0K5Garg6pnA34x .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aY0K5Garg6pnA34x .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aY0K5Garg6pnA34x .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aY0K5Garg6pnA34x .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aY0K5Garg6pnA34x .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aY0K5Garg6pnA34x .cluster text{fill:#333;}#mermaid-svg-aY0K5Garg6pnA34x .cluster span{color:#333;}#mermaid-svg-aY0K5Garg6pnA34x div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aY0K5Garg6pnA34x .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aY0K5Garg6pnA34x rect.text{fill:none;stroke-width:0;}#mermaid-svg-aY0K5Garg6pnA34x .icon-shape,#mermaid-svg-aY0K5Garg6pnA34x .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aY0K5Garg6pnA34x .icon-shape p,#mermaid-svg-aY0K5Garg6pnA34x .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aY0K5Garg6pnA34x .icon-shape .label rect,#mermaid-svg-aY0K5Garg6pnA34x .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aY0K5Garg6pnA34x .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aY0K5Garg6pnA34x .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aY0K5Garg6pnA34x :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Linux 内核
应用进程
System Server 进程

  1. 定时检测 (30s)
  2. 尝试获取锁
  3. 检查是否死锁
  4. 检查是否阻塞
  5. 检测应用主线程
  6. 超时 (5s/10s/60s)
  7. 触发 ANR
  8. 生成 traces.txt
  9. Native Crash
  10. 发送 SIGABRT
  11. 生成 tombstone_XX
  12. 发送 SIGQUIT
  13. dump 堆栈
    Watchdog 线程
    ActivityManagerService
    WindowManagerService
    PackageManagerService
    Monitor 接口
    主线程 (Main Looper)
    Binder 线程
    信号机制 (SIGQUIT/SIGABRT)
    Tombstone 生成器
    /data/anr/

2.2 核心监控组件职责表

组件 层级 职责 学术定义
Watchdog System Server 系统监护 监测 System Server 内部死锁和阻塞。
ActivityManagerService System Server 应用监护 监测应用主线程的响应时间。
Monitor Interface 死锁探测 通过尝试获取锁来检测死锁。
Signal Catcher ART Runtime 信号捕获 捕获 SIGQUIT 信号,dump Java 堆栈。
Debuggerd Native Daemon 墓碑生成 捕获 Native Crash,生成 Tombstone。

3. Watchdog 的死锁检测机制

3.1 Watchdog 的工作流程

Watchdog 是一个死循环线程,每隔一定时间(默认 30 秒)执行一次检测。

java 复制代码
// frameworks/base/services/core/java/com/android/server/Watchdog.java
public class Watchdog extends Thread {
    @Override
    public void run() {
        while (true) {
            // 1. 检查全局锁
            synchronized (mLock) {
                // 2. 检查 Monitor
                for (Monitor monitor : mMonitors) {
                    monitor.monitor(); // 尝试获取锁
                }
            }

            // 3. 等待一段时间
            wait(DEFAULT_TIMEOUT);

            // 4. 如果超时,触发重启
            if (isTimeout()) {
                rebootSystem("Watchdog triggered");
            }
        }
    }
}

3.2 Monitor 接口的实现

系统服务实现 Monitor 接口,在 monitor() 中尝试获取关键锁。

学术定义

  • 死锁检测 :如果 monitor() 方法阻塞,说明该服务的关键锁被其他线程持有,可能发生死锁。

  • 示例(ActivityManagerService)

    java 复制代码
    // ActivityManagerService.java
    public void monitor() {
        synchronized (this) { } // 尝试获取 AMS 的主锁
    }

3.3 重启策略

当 Watchdog 触发时,系统会采取不同级别的行动:

级别 行为 触发条件
Level 1 重启 System Server 单个服务死锁。
Level 2 重启 Zygote System Server 无法重启。
Level 3 重启 Android Runtime 严重 Native Crash。
Level 4 重启设备 Kernel Panic。

4. ANR 的检测与触发机制

4.1 ANR 的超时阈值

不同类型的组件有不同的超时时间。

组件类型 超时阈值 学术定义
Input Dispatch 5 秒 按键或触摸事件在 5 秒内未被分发。
BroadcastReceiver 10 秒 (前台) / 60 秒 (后台) onReceive() 执行超时。
Service 20 秒 (前台) / 200 秒 (后台) onCreate() / onStartCommand() 执行超时。
ContentProvider 10 秒 query() / insert() 执行超时。

4.2 ANR 的检测逻辑

ActivityManagerService 使用 HandlerMessage 检测超时。

java 复制代码
// ActivityManagerService.java
void appNotResponding(ProcessRecord app) {
    // 1. 获取应用主线程的 Looper
    final Looper looper = app.thread.getLooper();

    // 2. 发送一个 Message 到主线程
    Message msg = Message.obtain();
    msg.what = ANR_MSG;
    looper.sendMessage(msg);

    // 3. 设置一个定时器 (5秒)
    mHandler.sendMessageDelayed(mAnrTimeoutMsg, 5000);

    // 4. 如果 5 秒内主线程处理了 Message,取消定时器
    // 5. 如果 5 秒内未处理,定时器触发,执行 ANR 逻辑
}

4.3 ANR 时的信息收集

当 ANR 发生时,系统会收集大量信息:

  1. Java 堆栈 :通过发送 SIGQUIT 信号给应用进程,Signal Catcher 线程 dump 主线程堆栈。
  2. Native 堆栈:如果有 Native 代码,Debuggerd 会 dump Native 堆栈。
  3. 系统状态:CPU 使用率、内存状态、进程列表。
  4. Binder 状态:当前 Binder 调用栈,检测是否阻塞在 Binder 调用。

5. Native Crash 与 Tombstone

5.1 Native Crash 的信号处理

当 Native 层发生严重错误时,内核发送信号。

信号 含义 常见原因
SIGSEGV 段错误 空指针解引用、内存越界。
SIGABRT 异常终止 abort() 调用、assert() 失败。
SIGBUS 总线错误 内存对齐错误。
SIGILL 非法指令 执行了非法机器码。

5.2 Tombstone 文件结构

Tombstone 是一个文本文件,包含丰富的调试信息。

复制代码
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/crosshatch/crosshatch:11/RQ3A.210705.001/7475110:user/release-keys'
Revision: 'MP1.0'
ABI: 'arm64'
Timestamp: 2023-10-27 10:00:00+0800
pid: 12345, tid: 12347, name: Thread-2  >>> com.example.app <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    x0  0000000000000000  x1  0000007b3c001234  x2  0000000000000000  x3  0000007b3c001234
    x4  0000000000000000  x5  0000000000000000  x6  0000000000000000  x7  0000000000000000
    x8  0000000000000000  x9  0000007b3c001234  x10 0000000000000000  x11 0000000000000000
    x12 0000000000000000  x13 0000000000000000  x14 0000000000000000  x15 0000000000000000
    x16 0000007b3c001234  x17 0000007b3c001234  x18 0000000000000000  x19 0000000000000000
    x20 0000000000000000  x21 0000000000000000  x22 0000000000000000  x23 0000000000000000
    x24 0000000000000000  x25 0000000000000000  x26 0000000000000000  x27 0000000000000000
    x28 0000000000000000  x29 0000000000000000  x30 0000007b3c001234
    sp  0000007b3c001000  pc  0000007b3c001234  pstate 0000000000000000

backtrace:
    #00 pc 0000000000001234  /apex/com.android.runtime/lib64/libart.so (art::Runtime::Abort(char const*)+123)
    #01 pc 0000000000005678  /apex/com.android.runtime/lib64/libart.so (art::LogAbort(char const*, ...)+456)
    #02 pc 0000000000009abc  /data/app/com.example.app/lib/arm64/libnative-lib.so (crash_function+12)

学术定义

  • Registers: CPU 寄存器状态,用于定位崩溃指令。
  • Backtrace: 调用栈回溯,用于定位代码位置。
  • Maps: 内存映射,显示代码段、数据段、堆、栈的位置。

6. 关键源码深度解析

6.1 Watchdog 的 Monitor 检测

cpp 复制代码
// frameworks/base/services/core/java/com/android/server/Watchdog.java
private final ArrayList<Monitor> mMonitors = new ArrayList<>();

public void addMonitor(Monitor monitor) {
    synchronized (mLock) {
        mMonitors.add(monitor);
    }
}

void run() {
    while (true) {
        synchronized (mLock) {
            for (Monitor m : mMonitors) {
                // 关键:这里只是调用 monitor(),如果阻塞,整个 Watchdog 线程就卡住了
                m.monitor();
            }
        }
        // ... 等待和检查
    }
}

6.2 ANR 的 Signal 处理

java 复制代码
// frameworks/base/core/jni/android_os_Process.cpp
void signalCatcherThread() {
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGQUIT);
    sigwait(&mask, &sig); // 等待 SIGQUIT 信号

    // 收到信号,dump 堆栈
    dumpJavaStacks();
    dumpNativeStacks();
}

7. 稳定性系统的常见误区

误区 学术解释
ANR 一定是主线程死循环 不一定。可能是主线程阻塞在 I/O、Binder 调用或锁竞争。
Watchdog 重启能解决一切 不能。如果死锁发生在 Native 层或 Kernel 层,重启 System Server 无效。
Tombstone 只能分析 Native Crash 是的。Java Crash 由 logcat 记录,Tombstone 只记录 Native 层致命错误。
关闭 ANR 对话框就不会重启 错误。ANR 发生后,系统可能已经处于不稳定状态,关闭对话框只是掩盖问题。

8. 本篇总结(Knowledge Closure)

关键点 纯学术定义
Watchdog 的本质 系统服务的心跳监护仪,通过 Monitor 接口检测死锁。
ANR 的本质 应用主线程的超时陷阱,由 ActivityManagerService 检测并触发。
Monitor 机制 死锁探测接口,通过尝试获取关键锁来判断是否死锁。
Tombstone 的本质 进程临终快照,包含寄存器、堆栈和内存映射,用于事后分析。
Signal 机制 内核与用户空间的通信方式,用于触发堆栈 dump 和进程终止。

9. 第十板块结语

至此,第十板块:Android 系统稳定性与调试 的第一篇已完成。

我们从 Watchdog 的死锁检测 出发,深入 ANR 的超时监控 ,探索 Monitor 接口的心跳机制 ,最终抵达 Tombstone 的临终快照

我们揭示了 Android 稳定性系统的核心逻辑:用超时检测响应,用死锁检测阻塞,用信号触发诊断,用重启恢复服务。

下一篇预告第十板块:Android 系统稳定性与调试 | 第二十六篇:Systrace 与 Perfetto 的系统级性能分析

相关推荐
故渊at2 小时前
第十板块:Android 系统稳定性与调试 | 第二十六篇:Systrace 与 Perfetto 的系统级性能分析
android·perfetto·性能分析·systrace·系统稳定性
吕工-老船长19982 小时前
20260610----S905Y5(Android14)-----连接网络自动更新时间,时间设置为24小时
android
杉氧3 小时前
Kotlin 协程深度解析④:架构实战——在 MVVM/MVI 中的进阶应用
android·kotlin
Ab_stupid3 小时前
CTF-Android培训笔记
android·笔记
Ycocol4 小时前
AS同一个目录下的类导入导入其他类爆红无法跳转但是可以编译
android·ide·android studio
Meteors.4 小时前
安卓字节码插桩与埋点
android
故渊at5 小时前
第九板块:Android 多媒体体系 | 第二十三篇:AudioFlinger 与 AudioPolicyService 音频架构
android·架构·音视频·audiopolicy·audioflinger
故渊at5 小时前
第八板块:Android 网络体系与连接管理 | 第二十二篇:ConnectivityService 与 Netd 网络架构
android·网络·架构·连接管理·connectivity