Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

    • 如何调试 SurfaceFlinger
      • 1. 准备工作
      • 2. 日志调试
      • 3. VSCode 图形化调试
      • 总结
      • 参考资料
    • HWC 接口分析
    • SurfaceFlinger 概述
    • 启动过程总览
    • SurfaceFlinger 初始化
    • RenderEnginge 初始化
  • Framework
  • 显示系统
阿豪
2025-10-05
目录

如何调试 SurfaceFlinger

SurfaceFlinger 系列文章持续更新中(公众号:阿豪讲Framework):

  • 如何调试 SurfaceFlinger
  • SurfaceFlinger 概述
  • 启动过程总览
  • SurfaceFlinger 对象初始化
  • ........

工欲善其事,必先利其器!SurfaceFlinger 常用的调试手段主要有:

  1. 日志调试
  2. 单步调试
  3. Perfetto
  4. dumpsys SurfaceFlinger

本文主要讲解前两点,第三点在源码分析过程中穿插讲解,第四点在完成 SurfaceFlinger 核心流程与功能后讲解。

# 1. 准备工作

首先我们需要一份源码并编译出一个 eng 版本,这里我使用的是 aosp android-15.0.0_r20 源码,硬件上使用 pixel6 手机,其它 pixel 手机或者模拟器都类似。

source build/envsetup.sh
# pixel6
lunch aosp_oriole-bp1a-eng
# pixel8 pro
# lunch aosp_husky-bp1a-eng
m 
1
2
3
4
5
6

接着把镜像刷入手机:

adb reboot bootloader
fastboot flashall -w
1
2

接着我们需要再 VSCode 中安装好 CodeLLDB 插件

20240716161159

# 2. 日志调试

这里我们修改 SurfaceFlinger 的主函数 main_surfaceflinger.cpp 来演示打印 Log 和打印调用堆栈:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// 添加头文件和宏
#include "log/log.h"
//直接 define LOG_TAG 会报已定义错误,因为 SurFaceFlinger 模块的 Android.bp 已经定义了 LOG_Tag
//下面这样定义就不会出错了
#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "ahao-sf"
#endif
//打印堆栈的头文件
#include <utils/CallStack.h>

bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId,
                            const scheduler::FrameTargets& frameTargets) {
    const scheduler::FrameTarget& pacesetterFrameTarget = *frameTargets.get(pacesetterId)->get();

    // 添加日志
    ALOGD("SurfaceFlinger::commit");
    // 打印调用栈
    android::CallStack callStack(LOG_TAG, 1);

    const VsyncId vsyncId = pacesetterFrameTarget.vsyncId();

    // ......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

主要三个部分的修改:

  • 添加头文件和宏
  • 添加日志
  • 添加调用栈

修改 /frameworks/native/services/surfaceflinger/Android.bp,添加 CallStack 的库依赖:

接着单编 SurfaceFlinger:

# 源码目录下
source build/envsetup.sh
lunch aosp_oriole-bp1a-eng
make surfaceflinger
1
2
3
4

接着 push 到手机上:

adb push out/target/product/oriole/system/bin/surfaceflinger /system/bin 
adb reboot
1
2

最后验证查看日志:

adb logcat | grep "ahao-sf"
07-02 19:41:32.375   556   556 D ahao-sf : SurfaceFlinger::commit
07-02 19:41:32.385   556   556 D ahao-sf :   #00 pc 00000000002771a0  /system/bin/surfaceflinger (android::SurfaceFlinger::commit(android::PhysicalDisplayId, android::ftl::SmallMap<android::PhysicalDisplayId, android::scheduler::FrameTarget const*, 3ul, std::__1::equal_to<android::PhysicalDisplayId>> const&)+176) (BuildId: 5e135e484b98796bac0be1710386a2f2)
07-02 19:41:32.385   556   556 D ahao-sf :   #01 pc 000000000024dc10  /system/bin/surfaceflinger (android::scheduler::Scheduler::onFrameSignal(android::ICompositor&, android::VsyncId, android::TimePoint)+544) (BuildId: 5e135e484b98796bac0be1710386a2f2)
07-02 19:41:32.385   556   556 D ahao-sf :   #02 pc 0000000000011b50  /system/lib64/libutils.so (android::Looper::pollInner(int)+368) (BuildId: 100fa690ab318d6e1873d66d1c3f4c8e)
07-02 19:41:32.385   556   556 D ahao-sf :   #03 pc 000000000001197c  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+124) (BuildId: 100fa690ab318d6e1873d66d1c3f4c8e)
07-02 19:41:32.385   556   556 D ahao-sf :   #04 pc 000000000023a854  /system/bin/surfaceflinger (android::impl::MessageQueue::waitMessage()+84) (BuildId: 5e135e484b98796bac0be1710386a2f2)
07-02 19:41:32.385   556   556 D ahao-sf :   #05 pc 000000000024d9dc  /system/bin/surfaceflinger (android::scheduler::Scheduler::run()+28) (BuildId: 5e135e484b98796bac0be1710386a2f2)
07-02 19:41:32.385   556   556 D ahao-sf :   #06 pc 00000000002c6688  /system/bin/surfaceflinger (main+1272) (BuildId: 5e135e484b98796bac0be1710386a2f2)
07-02 19:41:32.385   556   556 D ahao-sf :   #07 pc 0000000000057854  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+116) (BuildId: f0cc3fe16b52af6fc8d4e5b18105de09)
1
2
3
4
5
6
7
8
9
10

# 3. VSCode 图形化调试

新开一个终端进入系统源码根目录,执行下面的命令:

source build/envsetup.sh
lunch aosp_oriole-bp1a-eng
1
2

手机打开 USB 调试并通过 USB 与手机相连,接着找到要调试的进程(surfaceflinger)对应的 pid

adb shell ps -elf | grep surfaceflinger

system       14330     1 0 20:20:06 ?     00:04:27 surfaceflinger
1
2
3

可以看出,surfaceflinger 进程的 pid 为 14330.

接着开启 lldb 服务端

lldbclient.py -p 14330 --setup-forwarding vscode-lldb
1

该命令会打印一段 json,记录下来(你的可能和我不一样):

{
    "name": "(lldbclient.py) Attach surfaceflinger (port: 5039)",
    "type": "lldb",
    "request": "custom",
    "relativePathBase": "/home/zzh0838/Project/aosp/android-15.0.0_r20",
    "sourceMap": {
        "/b/f/w": "/home/zzh0838/Project/aosp/android-15.0.0_r20",
        "": "/home/zzh0838/Project/aosp/android-15.0.0_r20",
        ".": "/home/zzh0838/Project/aosp/android-15.0.0_r20"
    },
    "initCommands": [
        "settings append target.exec-search-paths /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/ /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/hw /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/ssl/engines /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/drm /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/egl /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/soundfx /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/vendor/lib64/ /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/vendor/lib64/hw /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/vendor/lib64/egl /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/apex/com.android.runtime/bin"
    ],
    "targetCreateCommands": [
        "target create /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/bin/surfaceflinger",
        "target modules search-paths add / /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/"
    ],
    "processCreateCommands": [
        "gdb-remote 5039"
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

接下来使用 VSCode 打开 Android 源码的根目录。

接着点击菜单栏的 run -> Add Configuration:

20250702151407

选择 LLDB:

20250702151553

接着就会在根目录下生成一个 .vscode 文件夹,其中有一个 launch.json 文件。

20250702172346

接着把 .vscode/launch.json 文件中 configurations 节点的内容都删掉,换成上面记录的 json:

{
{
    "configurations": [ 
    {
    "name": "(lldbclient.py) Attach surfaceflinger (port: 5039)",
    "type": "lldb",
    "request": "custom",
    "relativePathBase": "/home/zzh0838/Project/aosp/android-15.0.0_r20",
    "sourceMap": {
        "/b/f/w": "/home/zzh0838/Project/aosp/android-15.0.0_r20",
        "": "/home/zzh0838/Project/aosp/android-15.0.0_r20",
        ".": "/home/zzh0838/Project/aosp/android-15.0.0_r20"
    },
    "initCommands": [
        "settings append target.exec-search-paths /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/ /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/hw /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/ssl/engines /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/drm /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/egl /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/lib64/soundfx /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/vendor/lib64/ /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/vendor/lib64/hw /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/vendor/lib64/egl /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/apex/com.android.runtime/bin"
    ],
    "targetCreateCommands": [
        "target create /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/system/bin/surfaceflinger",
        "target modules search-paths add / /home/zzh0838/Project/aosp/android-15.0.0_r20/out/target/product/oriole/symbols/"
    ],
    "processCreateCommands": [
        "gdb-remote 5039"
    ]
} 
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

接着在 frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 文件中打好断点:

20250702172519

然后点击菜单栏 run -> Start Debugging 开始调试:

20250702172616

此时,进入到调试模式。

接着操作手机,点击一个 App 图标,VSCode 就会进入到断点处:

20250702173040

# 总结

写码十分钟,调试一整天!

# 参考资料

  • Use debuggers (opens new window)
#显示系统
026.AIDL Hal 开发指南10 —— AIDL HAL 的升级
HWC 接口分析

← 026.AIDL Hal 开发指南10 —— AIDL HAL 的升级 HWC 接口分析→

最近更新
01
SurfaceFlinger 概述
10-05
02
HWC 接口分析
10-05
03
启动过程总览
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式