转自:http://blueredfield.blog.163.com/blog/static/11535200020115301093925/
http://blog.youkuaiyun.com/skywalkzf/article/details/6733944
1、在默认情况下,adb logcat只能显示应用程序的调试信息,我把logcat.cpp修改了一下,让它同时可以打印内核调试信息:
system/core/logcat/logcat.cpp
static void readLogLines(int logfd)
{
char buffer[256] = {0};
while (1) {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4)));
struct logger_entry *entry = (struct logger_entry *) buf;
int ret;
ret = read(logfd, entry, LOGGER_ENTRY_MAX_LEN);
if (ret < 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN)
break;
perror("logcat read");
exit(EXIT_FAILURE);
}
else if (!ret) {
fprintf(stderr, "read: Unexpected EOF!\n");
exit(EXIT_FAILURE);
}
/* NOTE: driver guarantees we read exactly one full entry */
entry->msg[entry->len] = '\0';
if (g_printBinary) {
printBinary(entry);
} else {
(void) processBuffer(entry);
}
/*读入内核调试信息*/
if((ret = klogctl(9, buffer, sizeof(buffer))) > 0) {
if((ret = klogctl(2, buffer, sizeof(buffer))) > 0) {
entry->tid = 0;
entry->pid = getpid();
/*priority*/
entry->msg[0] = ANDROID_LOG_INFO;
/*tag*/
strcpy(entry->msg+1, KERNEL_TAG);
/*message*/
strncpy(entry->msg+1+sizeof(KERNEL_TAG), buffer, ret);
entry->len = 1 + sizeof(KERNEL_TAG) + ret + 1;
entry->msg[entry->len] = '\0';
if (g_printBinary) {
printBinary(entry);
} else {
(void) processBuffer(entry);
}
}
}
}
}
这里没有把内核调试信息的级别转换成Androind的LOG级别,全部使用了ANDROID_LOG_INFO级别,进程ID用了当前的进程ID
2、
Android让adb logcat打印内核调试信息
在默认情况下,adb logcat只能显示应用程序的调试信息,我把logcat.cpp修改了一下,让它同时可以打印内核调试信息:
修改的文件:system/core/logcat/logcat.cpp
1、首先先加入头文件
#include <sys/klog.h> //add by
2、定义所使用的TAG
#define KERNEL_TAG "Kernel"
3、替换readLogLines函数
{
log_device_t* dev;
int max = 0;
int ret;
int queued_lines = 0;
bool sleep = true;
char buffer[256] = {0}; //add by zhaofei
int result;
fd_set readset;
for (dev=devices; dev; dev = dev->next) {
if (dev->fd > max) {
max = dev->fd;
}
}
while (1) {
do {
timeval timeout = { 0, 5000 /* 5ms */ }; // If we oversleep it's ok, i.e. ignore EINTR.
FD_ZERO(&readset);
for (dev=devices; dev; dev = dev->next) {
FD_SET(dev->fd, &readset);
}
result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout);
} while (result == -1 && errno == EINTR);
if (result >= 0) {
for (dev=devices; dev; dev = dev->next) {
if (FD_ISSET(dev->fd, &readset)) {
queued_entry_t* entry = new queued_entry_t();
/* NOTE: driver guarantees we read exactly one full entry */
ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN);
if (ret < 0) {
if (errno == EINTR) {
delete entry;
goto next;
}
if (errno == EAGAIN) {
delete entry;
break;
}
perror("logcat read");
exit(EXIT_FAILURE);
}
else if (!ret) {
fprintf(stderr, "read: Unexpected EOF!\n");
exit(EXIT_FAILURE);
}
entry->entry.msg[entry->entry.len] = '\0';
dev->enqueue(entry);
++queued_lines;
#if 1 //read kernel log
if((ret = klogctl(9, buffer, sizeof(buffer))) > 0) {
if((ret = klogctl(2, buffer, sizeof(buffer))) > 0) {
entry->entry.tid = 0;
entry->entry.pid = getpid();
/*priority*/
entry->entry.msg[0] = ANDROID_LOG_INFO;
/*tag*/
strcpy(entry->entry.msg+1, KERNEL_TAG);
/*message*/
strncpy(entry->entry.msg+1+sizeof(KERNEL_TAG), buffer, ret);
entry->entry.len = 1 + sizeof(KERNEL_TAG) + ret + 1;
entry->entry.msg[entry->entry.len] = '/0';
/*
if (g_printBinary) {
printBinary(dev, entry->entry);
} else {
(void) processBuffer(dev, entry->entry);
}
*/
printNextEntry(dev);
}
}
#endif
}
}
if (result == 0) {
// we did our short timeout trick and there's nothing new
// print everything we have and wait for more data
sleep = true;
while (true) {
chooseFirst(devices, &dev);
if (dev == NULL) {
break;
}
if (g_tail_lines == 0 || queued_lines <= g_tail_lines) {
printNextEntry(dev);
} else {
skipNextEntry(dev);
}
--queued_lines;
}
// the caller requested to just dump the log and exit
if (g_nonblock) {
exit(0);
}
} else {
// print all that aren't the last in their list
sleep = false;
while (g_tail_lines == 0 || queued_lines > g_tail_lines) {
chooseFirst(devices, &dev);
if (dev == NULL || dev->queue->next == NULL) {
break;
}
if (g_tail_lines == 0) {
printNextEntry(dev);
} else {
skipNextEntry(dev);
}
--queued_lines;
}
}
}
next:
;
}
}
这里没有把内核调试信息的级别转换成Androind的LOG级别,entry->entry.msg[0] = ANDROID_LOG_INFO;使用了ANDROID_LOG_INFO级别,进程ID用了当前的进程ID。
然后就可以使用logcat来抓取kernel的log了!