logcat机制
framework层:
frameworks/base/core/java/android/util/Log.java该文件定义且实现了Log类
在类中各种log记录方法都依赖于native的实现println_native(),类中的log.v()等方法最终都是调用了println_native()。
native方法println_native()是通过JNI在c/c++中实现的。
Log类里有两个jni函数:
publicstatic native boolean isLoggable(string tag,int level)
publicstatic native int println_native(int bufID,int priority,stringtag,string msg)
Jni层:
isLoggable,println_native,这两个方法在frameworks/base/core/jni/android_util_log.cpp中实现。
JNIregistration:
staticJNINativeMethod gMethods[] = {
{"isLoggable", "(Ljava/lang/String;I)Z",(void*) android_util_Log_isLoggable },
{"println_native", "(IILjava/lang/String;Ljava/lang/String;)I", (void*)android_util_Log_println_native },
};
isLoggable的实现是比较level,看记录信息等级是否需要被记录;
println_native()函数则是实现的想log设备内写log信息:
(frameworks/base/core/jni/android_util_log.cpp)android_util_Log_println_native
---》(system/core/liblog/logd_write.c) __android_log_buf_write
---》(system/core/liblog/logd_write.c)write_to_log:__write_to_log_kernel (这一步还是有个__write_to_log_init初始化log设备)
---》(system/core/liblog/logd_write.c)log_writev:这个函数是宏函数,替换为fakeLogWritev或者writev,但是fakeLogWritev最后也调用了writev函数。
---》(system/core/liblog/fake_log_device.c)fakeLogWritev
---》(system/core/liblog/fake_log_device.c)redirectWritev:函数里调用writev或者logWritev,writev是可能是写到真机里会用到,logWritev可能是虚拟环境
---》(system/core/libcutils/uio.c)writev: 这个函数声明在system/core/include/cutils/uio.h里,log.h文件include了它。
---》(system/core/libcutils/uio.c)write:这函数是系统调用应该是通过bionic调用内核write函数,然后将log写进设备文件,在这些调用过程中已经指定设备文件。
logger驱动
PS:内核层,主要是初始设备文件,提供file_operations给内核,让内核肯对设备文件进行操作。这里的设备文件好像就是内存。
logger驱动程序模块的初始化过程分析。
./drivers/staging/android/logger.c文件中通过DEFINE_LOGGER_DEVICE()宏函数创建了三个日志设备:
DEFINE_LOGGER_DEVICE(log_main,LOGGER_LOG_MAIN, 64*1024)
DEFINE_LOGGER_DEVICE(log_events,LOGGER_LOG_EVENTS, 256*1024)
DEFINE_LOGGER_DEVICE(log_radio,LOGGER_LOG_RADIO, 64*1024)
看看这三个日志设备的用途:注册日志设备文件操作方法为logger_fops:
staticstruct file_operations logger_fops = {
.owner= THIS_MODULE,
.read= logger_read, //读
.aio_write= logger_aio_write, //写
.poll= logger_poll,
.unlocked_ioctl= logger_ioctl,
.compat_ioctl= logger_ioctl,
.open= logger_open,
.release= logger_release,
};