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函数

  1. static void readLogLines(log_device_t* devices)  
  2. {  
  3.     log_device_t* dev;  
  4.     int max = 0;  
  5.     int ret;  
  6.     int queued_lines = 0;  
  7.     bool sleep = true;  
  8.     char buffer[256] = {0}; //add by zhaofei   
  9.   
  10.   
  11.     int result;  
  12.     fd_set readset;  
  13.   
  14.   
  15.     for (dev=devices; dev; dev = dev->next) {  
  16.         if (dev->fd > max) {  
  17.             max = dev->fd;  
  18.         }  
  19.     }  
  20.   
  21.   
  22.     while (1) {  
  23.         do {  
  24.             timeval timeout = { 0, 5000 /* 5ms */ }; // If we oversleep it's ok, i.e. ignore EINTR.   
  25.             FD_ZERO(&readset);  
  26.             for (dev=devices; dev; dev = dev->next) {  
  27.                 FD_SET(dev->fd, &readset);  
  28.             }  
  29.             result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout);  
  30.         } while (result == -1 && errno == EINTR);  
  31.   
  32.   
  33.         if (result >= 0) {  
  34.             for (dev=devices; dev; dev = dev->next) {  
  35.                 if (FD_ISSET(dev->fd, &readset)) {  
  36.                     queued_entry_t* entry = new queued_entry_t();  
  37.                     /* NOTE: driver guarantees we read exactly one full entry */  
  38.                     ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN);  
  39.                     if (ret < 0) {  
  40.                         if (errno == EINTR) {  
  41.                             delete entry;  
  42.                             goto next;  
  43.                         }  
  44.                         if (errno == EAGAIN) {  
  45.                             delete entry;  
  46.                             break;  
  47.                         }  
  48.                         perror("logcat read");  
  49.                         exit(EXIT_FAILURE);  
  50.                     }  
  51.                     else if (!ret) {  
  52.                         fprintf(stderr, "read: Unexpected EOF!\n");  
  53.                         exit(EXIT_FAILURE);  
  54.                     }  
  55.   
  56.   
  57.                     entry->entry.msg[entry->entry.len] = '\0';  
  58.   
  59.   
  60.                     dev->enqueue(entry);  
  61.                     ++queued_lines;  
  62.   
  63.   
  64. #if 1 //read kernel log   
  65.                     if((ret = klogctl(9, buffer, sizeof(buffer))) > 0) {  
  66.                         if((ret = klogctl(2, buffer, sizeof(buffer))) > 0) {  
  67.                             entry->entry.tid = 0;  
  68.                             entry->entry.pid = getpid();  
  69.                             /*priority*/  
  70.                             entry->entry.msg[0] = Android_LOG_INFO;  
  71.                             /*tag*/  
  72.                             strcpy(entry->entry.msg+1, KERNEL_TAG);  
  73.                             /*message*/  
  74.                             strncpy(entry->entry.msg+1+sizeof(KERNEL_TAG), buffer, ret);  
  75.                             entry->entry.len = 1 + sizeof(KERNEL_TAG) + ret + 1;  
  76.                             entry->entry.msg[entry->entry.len] = '/0';  
  77.                             /* 
  78.                             if (g_printBinary) { 
  79.                                 printBinary(dev, entry->entry); 
  80.                             } else { 
  81.                                 (void) processBuffer(dev, entry->entry); 
  82.                             } 
  83.                             */  
  84.                         printNextEntry(dev);  
  85.                         }  
  86.                     }  
  87. #endif   
  88.                 }  
  89.             }  
  90.   
  91.   
  92.             if (result == 0) {  
  93.                 // we did our short timeout trick and there's nothing new   
  94.                 // print everything we have and wait for more data   
  95.                 sleep = true;  
  96.                 while (true) {  
  97.                     chooseFirst(devices, &dev);  
  98.                     if (dev == NULL) {  
  99.                         break;  
  100.                     }  
  101.                     if (g_tail_lines == 0 || queued_lines <= g_tail_lines) {  
  102.                         printNextEntry(dev);  
  103.                     } else {  
  104.                         skipNextEntry(dev);  
  105.                     }  
  106.                     --queued_lines;  
  107.                 }  
  108.   
  109.   
  110.                 // the caller requested to just dump the log and exit   
  111.                 if (g_nonblock) {  
  112.                     exit(0);  
  113.                 }  
  114.             } else {  
  115.                 // print all that aren't the last in their list   
  116.                 sleep = false;  
  117.                 while (g_tail_lines == 0 || queued_lines > g_tail_lines) {  
  118.                     chooseFirst(devices, &dev);  
  119.                     if (dev == NULL || dev->queue->next == NULL) {  
  120.                         break;  
  121.                     }  
  122.                     if (g_tail_lines == 0) {  
  123.                         printNextEntry(dev);  
  124.                     } else {  
  125.                         skipNextEntry(dev);  
  126.                     }  
  127.                     --queued_lines;  
  128.                 }  
  129.             }  
  130.         }  
  131. next:  
  132.         ;  
  133.     }  
  134. }  
这里没有把内核调试信息的级别转换成Androind的LOG级别,entry->entry.msg[0] = ANDROID_LOG_INFO;使用了ANDROID_LOG_INFO级别,进程ID用了当前的进程ID。

然后就可以使用logcat来抓取kernel的log了!

相关内容