基于Android N的Log机制浅析 下篇

本文深入探讨Android N中logd模块的启动、写入与读取Log的过程。logd作为独立进程由init启动,监听socket进行数据交互。LogListener监听写入请求,LogReader负责通知读取进程。logd通过LogBuffer存储Log,当达到Buffer大小限制时进行清理。Log打印实际是将Log写入logd内存,再由读取工具如adb shell logcat读取并处理。
摘要由CSDN通过智能技术生成

在上篇中从上层使用Log的java接口讲到了liblog中,最终通过socket将要打印的Log交给了logd模块处理,本篇就继续来看一下logd模块内部对Log的处理过程。

Logd的启动

Logd模块是单独跑在一个进程中的,该进程是直接由init进程fork出来的子进程。

shell@M3X:/ $ ps | grep zygote
root      343   1     2137408 86344 poll_sched 0000000000 S zygote64
root      344   1     1579728 75304 poll_sched 0000000000 S zygote
shell@M3X:/ $ ps | grep logd                                                   
logd      268   1     27136  3724  sigsuspend 0000000000 S /system/bin/logd
shell@M3X:/ $ ps | grep init                                                   
root      1     0     13112  1364  SyS_epoll_ 0000000000 S /init
system    293   1     13316  1644  dev_char_r 0000000000 S /system/bin/ccci_mdinit
system    295   1     12284  1636  dev_char_r 0000000000 S /system/bin/ccci_mdinit

通过ps可以看到logd进程和zygote一样,他们的ppid都是1,而1正是init进程的pid,所以也印证了他们都是由init进程fork出来的结论,当然你也可以去查看一下系统中的init.rc文件,里面也详细描述了启动logd的时机。

Logd启动后的入口是/system/core/logd/main.cpp中的main方法,本文聚焦上层打印Log后Logd的处理过程,因此省略部分代码:

int main(int argc, char *argv[]) {

    ...

    // LogBuffer is the object which is responsible for holding all
    // log entries.

    logBuf = new LogBuffer(times);

    // LogReader listens on /dev/socket/logdr. When a client
    // connects, log entries in the LogBuffer are written to the client.

    LogReader *reader = new LogReader(logBuf);
    if (reader->startListener()) {
        exit(1);
    }

    // LogListener listens on /dev/socket/logdw for client
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    LogListener *swl = new LogListener(logBuf, reader);
    // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
    if (swl->startListener(600)) {
        exit(1);
    }

    ...

}

上面的代码在Logd进程启动后执行,省略了部分初始化工作的代码,这里主看到构造了一个LogBuffer类型的对象logBuf,它的作用是真正存放写入的log。然后构造了一个LogReader类型的对象reader,并将上面构造的logBuf当做参数传给reader,它的作用主要是监听LogBuffer中log的变化或者是否有进程想要读取logd中的log,在有新的log写入时能够被及时通知到,然后可以通过socket通知log的读取方将log取出,通过其startListener()方法开始监听socket是否有请求(比如adb shell logcat)。接下来构造了一个LogListener类型的对象swl,并将r

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值