Android高级调试之surfaceflinger(上)

本文介绍了Android系统中的SurfaceFlinger高级调试,包括BufferQueue+SurfaceControl和ASurfaceControl的工作原理,以及如何使用Nano Code进行调试。内容涉及SurfaceFlinger的启动流程、源码分析和调试技巧,为理解Android显示系统提供深入洞见。
摘要由CSDN通过智能技术生成

Android高级调试之surfaceflinger(上)

surfaceflinger介绍


SurfaceFlinger的作用是接受缓冲区并对它们进行合成,然后发送到屏幕,其中缓冲区的数据是WindowManager提供的。
SurfaceFlinger可通过两种方式接受缓冲区:分别是BufferQueue+SurfaceControl和ASurfaceControl。


BufferQueue+SurfaceControl


当应用进入前台时,它会从WindowManager请求缓冲区。然后WindowManager会从SurfaceFlinger请求BufferQueue+SurfaceControl。
SurfaceFlinger创建Surface并将其发送至WindowManager。然后,WindowManager将Surface发送至应用,但会保留 SurfaceControl来操控应用在屏幕上的外观。


ASurfaceControl


ASurfaceControl是安卓10开始引入的。
ASurfaceControl将Surface和SurfaceControl组合到一个包中,该包会被发送至 SurfaceFlinger。ASurfaceControl与Surface相关联,应用可通过 ASurfaceTransactions更新该Surface。然后,应用可通过回调(用于传递包含锁定时间、获取时间等信息的ASurfaceTransactionStats)获取有关 ASurfaceTransactions的信息。


安装Nano Code


Nano Code下载链接:https://www.nanocode.cn/#/download
注:未注册用户,在注册后才可以使用调试功能。


准备调试


a. 连接到远端服务,设置好IP后,点击连接。
```c
tcp:port=portID,server=ipAddress
example: tcp:port=2021,server=192.168.7.200
端口取决于ndstub,默认为2021.
```

 
b. 选择附加到进程,选择机器和进程后,点击附加。

 
c. 成功附加到进程。

 
启动流程概览


可以通过下面的链接下载surfaceflinger的源代码。
https://gedu.oss-cn-beijing.aliyuncs.com/android_gdk850/services.tar.gz
下面的main函数代码是surfaceflinger的起点,通过这个函数我们可以知道surfacefliger是如何一点点进入run函数内的。

int main(int, char**) {
    signal(SIGPIPE, SIG_IGN);

    hardware::configureRpcThreadpool(1 /* maxThreads */,
            false /* callerWillJoin */);

    startGraphicsAllocatorService();

    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);

    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();

    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();

    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);

    // Put most SurfaceFlinger threads in the system-background cpuset
    // Keeps us from unnecessarily using big cores
    // Do this after the binder thread pool init
    if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);

    // initialize before clients can connect
    flinger->init();

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    startDisplayService(); // dependency on SF getting registered above

    if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
        ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));
    }

    // run surface flinger in this thread
    flinger->run();

    return 0;
}

为了观察surfaceflinger的main函数操作,首先需要在surfaceflinger!main处设置断点。

bl
 0 e 00000059`683d1048     0001 (0001)  0:|surfaceflinger!main

然后跑起来,当断点命中后,看一下当调试器停在main函数时的栈回溯。

k
Child-SP          RetAddr           Call Site
0000007f`e81dbf10 00000077`6e8eaa38 surfaceflinger!main+0x4
0000007f`e81dbf10 0000005c`4504d048 libselinux!ResetNativeLoader+0x9f163

libselinux!ResetNativeLoader的作用是当JavaVM销毁时,对相关信息进行清理。
可以看到surfaceflinger!main+0x4多走了一点,这是为了看到栈回溯而做的,避免刚停在某函数时,栈帧没有建立起来,导致看不到栈回溯。
通过~*查看线程,可以看到只有一个主线程存在,其他线程还没起来。

~*
.  0  Id: 720.720 Suspend: 1 Teb: 00000000`00000000 Unfrozen
      Start: surfaceflinger!__libc_init (00000059`683cf000) 
    +000 ti_ta_p:000000000000001E /* Process handle */
    +008 ti_user_flags:0x0 /* Unused */
    +010 ti_tid:0n933220608 /* Thread ID returned by pthread_create() */
    +018 ti_tls:0000000000000000 /* Pointer to thread-local data */
    +020 ti_startfunc:0000000000186A00 /* Start function passed to pthread_create() */
    +028 ti_stkbase:00000000000AAE60 /* Base of thread's stack */
    +030 ti_stksize:0x683cf000 /* Size of thread's stack */
    +038 ti_ro_area:0000000000000000 /* Unused */
    +040 ti_ro_size:0n0 /* Unused */
    +044 ti_state:0n0 /* Thread state */
    +048 ti_db_suspended:0n0 /* Nonzero if suspended by debugger */
    +04c ti_type:0n0 /* Type of the thread (system vs user thread) */
    +050 ti_pc:0n0 /* Unused */
    +058 ti_sp:0n0 /* Unused */
    +060 ti_flags:0n0 /* Unused */
    +064 ti_pri:0n0 /* Thread priority */
    +068 ti_lid:0n0 /* Kernel PID for this thread */
    +0f0 ti_traceme:0n0 /* Nonzero if event reporting enabled */
    +0f1 ti_preemptflag:0n0 /* Unused */
    +0f2 ti_pirecflag:0n0 /* Unused */

surfaceflinger首先忽略掉了SIGPPE,这是因为跨进程通信机制可能导致SIGPPE信号的发出,为了避免程序中止,所以使用signal函数抓住这个信号,并忽略掉。

signal函数定义:
void (*signal(int sig, void (*func)(int)))(int)

func这个参数可以使用SIG_DFL(默认的信号处理程序)或SIG_IGN(忽略信号),也可以自定义一个函数,指定收到信号时,程序应该做出的操作。

完成忽略信号的操作后,surfaceflinger就开始建立线程池,在Nano Code内可以通过~*命令查看全部线程,对比最上面的线程可以看到,这个时候surfaceflinger的线程已经完成建立了。

~*
.  0  Id: 9b.9b Suspend: 1 Teb: 00000000`00000000 Unfrozen
      Start: surfaceflinger!__libc_init (00000064`4b969000)
    &
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值