之前我们分析了如何修改版本使log机制变成kernel的log机制。这篇博客我们继续修改可以动态切换,这样方便平时log丢失时调试。


我们先来看liblog库的编译mk文件,这个文件中主要修改了对使用使用logd 使用不同文件进行编译这块做了修改,增加了log_write_common.c 和log_read_common.c两个通用文件。

[html]  view plain  copy
  1. #  
  2. # Copyright (C) 2008-2014 The Android Open Source Project  
  3. #  
  4. # Licensed under the Apache License, Version 2.0 (the "License");  
  5. # you may not use this file except in compliance with the License.  
  6. # You may obtain a copy of the License at  
  7. #  
  8. #      http://www.apache.org/licenses/LICENSE-2.0  
  9. #  
  10. # Unless required by applicable law or agreed to in writing, software  
  11. # distributed under the License is distributed on an "AS IS" BASIS,  
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13. # See the License for the specific language governing permissions and  
  14. # limitations under the License.  
  15. #  
  16. LOCAL_PATH := $(my-dir)  
  17. include $(CLEAR_VARS)  
  18.   
  19. # This is what we want to do:  
  20. #  liblog_cflags := $(shell \  
  21. #   sed -n \  
  22. #       's/^ [09] [ \t]*liblog[ \t].*/-DLIBLOG_LOG_TAG=\1/p' \  
  23. #       $(LOCAL_PATH)/event.logtags)  
  24. # so make sure we do not regret hard-coding it as follows:  
  25. liblog_cflags :-DLIBLOG_LOG_TAG=1005  
  26.   
  27. #ifneq ($(TARGET_USES_LOGD),false)//注释了 不需要区分使用使用logd  
  28. #liblog_sources :logd_write.c log_event_write.c  
  29. #else  
  30. #liblog_sources :logd_write_kern.c log_event_write.c  
  31. #endif  
  32.   
  33.   
  34. liblog_sources :log_write_common.c log_event_write.c//增加log_write_common.c   
  35.   
  36. # some files must not be compiled when building against Mingw  
  37. # they correspond to features not used by our host development tools  
  38. # which are also hard or even impossible to port to native Win32  
  39.   
  40. ifeq ($(strip $(USE_MINGW)),)  
  41.     liblog_sources += \  
  42.         event_tag_map.c  
  43. else  
  44.     liblog_sources += \  
  45.         uio.c  
  46. endif  
  47.   
  48. liblog_host_sources := $(liblog_sources) fake_log_device.c event.logtags  
  49. liblog_target_sources := $(liblog_sources) log_time.cpp log_is_loggable.c  
  50. ifeq ($(strip $(USE_MINGW)),)  
  51. liblog_target_sources += logprint.c  
  52. endif  
  53.   
  54. #ifneq ($(TARGET_USES_LOGD),false)//注释了,不用区分是否使用logd  
  55. #liblog_target_sources += log_read.c  
  56. #else  
  57. #liblog_target_sources += log_read_kern.c  
  58. #endif  
  59.   
  60. liblog_target_sources += log_read_common.c//增加log_read_common.c  
  61. # Shared and static library for host  
  62. # ========================================================  
  63. LOCAL_MODULE :liblog  
  64. LOCAL_SRC_FILES := $(liblog_host_sources)  
  65. LOCAL_CFLAGS :-DFAKE_LOG_DEVICE=1 -Werror $(liblog_cflags)  
  66. LOCAL_MULTILIB :both  
  67. include $(BUILD_HOST_STATIC_LIBRARY)  
  68.   
  69. include $(CLEAR_VARS)  
  70. LOCAL_MODULE :liblog  
  71. LOCAL_WHOLE_STATIC_LIBRARIES :liblog  
  72. ifeq ($(strip $(HOST_OS)),linux)  
  73. LOCAL_LDLIBS := -lrt  
  74. endif  
  75. LOCAL_MULTILIB :both  
  76. include $(BUILD_HOST_SHARED_LIBRARY)  
  77.   
  78.   
  79. # Shared and static library for target  
  80. # ========================================================  
  81. include $(CLEAR_VARS)  
  82. LOCAL_MODULE :liblog  
  83. LOCAL_SRC_FILES := $(liblog_target_sources)  
  84. LOCAL_CFLAGS := -Werror $(liblog_cflags)  
  85. include $(BUILD_STATIC_LIBRARY)  
  86.   
  87. include $(CLEAR_VARS)  
  88. LOCAL_MODULE :liblog  
  89. LOCAL_WHOLE_STATIC_LIBRARIES :liblog  
  90. LOCAL_CFLAGS := -Werror $(liblog_cflags)  
  91.   
  92. # TODO: This is to work around b/19059885. Remove after root cause is fixed  
  93. LOCAL_LDFLAGS_arm := -Wl,--hash-style=both  
  94.   
  95. include $(BUILD_SHARED_LIBRARY)  
  96.   
  97. include $(call first-makefiles-under,$(LOCAL_PATH))  

我们先来看log_read_common.c文件,这样主要就是将原来的logd_write.c 和logd_write_kern.c 文件进行合并。一些对外的接口,统一使用use_logd这个全局变量来控制,选择logd的函数,还是kernel的函数(logd的函数和kernel的函数就是static函数了,不用对外)。另外在__write_to_log_init函数中,第一次初始化的使用,先看system/etc/disable_logd是否有这样一个文件,有就将use_logd为0,代表使用kernel机制。

[cpp]  view plain  copy
  1. /* 
  2.  * Copyright (C) 2007-2014 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16. #if (FAKE_LOG_DEVICE == 0)  
  17. #include   
  18. #endif  
  19. #include   
  20. #include   
  21. #if !defined(_WIN32)  
  22. #include   
  23. #endif  
  24. #include   
  25. #include   
  26. #include   
  27. #include   
  28. #include   
  29. #include   
  30. #include   
  31. #if (FAKE_LOG_DEVICE == 0)  
  32. #include   
  33. #include   
  34. #endif  
  35. #include   
  36. #include   
  37.   
  38. #ifdef __BIONIC__  
  39. #include   
  40. #endif  
  41.   
  42. #include   
  43. #include   
  44. #include   
  45.   
  46. #include   
  47. #include   
  48. #include   
  49.   
  50. #define LOGGER_LOG_MAIN     "log/main"  
  51. #define LOGGER_LOG_RADIO    "log/radio"  
  52. #define LOGGER_LOG_EVENTS   "log/events"  
  53. #define LOGGER_LOG_SYSTEM   "log/system"  
  54.   
  55. #define LOG_BUF_SIZE 1024  
  56.   
  57. #if FAKE_LOG_DEVICE  
  58. /* This will be defined when building for the host. */  
  59. #include "fake_log_device.h"  
  60. #endif  
  61.   
  62. #define log_open(pathname, flags) open(pathname, (flags) | O_CLOEXEC)  
  63. #define log_writev(filedes, vector, count) writev(filedes, vector, count)  
  64. #define log_close(filedes) close(filedes)  
  65.   
  66. static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);  
  67. static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;  
  68. #if !defined(_WIN32)  
  69. static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;  
  70. #endif  
  71.   
  72. #ifndef __unused  
  73. #define __unused  __attribute__((__unused__))  
  74. #endif  
  75.   
  76. static int8_t use_logd = 1;//做区分  
  77.   
  78. #if FAKE_LOG_DEVICE  
  79. static int log_fds_fake[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };  
  80. #else  
  81. static int logd_fd = -1;  
  82. static int pstore_fd = -1;  
  83. #endif  
  84.   
  85. static int log_fds_kernel[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };  
  86.   
  87.   
  88. /* 
  89.  * This is used by the C++ code to decide if it should write logs through 
  90.  * the C code.  Basically, if /dev/socket/logd is available, we're running in 
  91.  * the simulator rather than a desktop tool and want to use the device. 
  92.  */  
  93. static enum {  
  94.     kLogUninitialized, kLogNotAvailable, kLogAvailable  
  95. } g_log_status = kLogUninitialized;  
  96.   
  97. static int __android_log_dev_available_logd(void)  
  98. {  
  99.     if (g_log_status == kLogUninitialized) {  
  100.         if (access("/dev/socket/logdw", W_OK) == 0)  
  101.             g_log_status = kLogAvailable;  
  102.         else  
  103.             g_log_status = kLogNotAvailable;  
  104.     }  
  105.   
  106.     return (g_log_status == kLogAvailable);  
  107. }  
  108.   
  109. static int __android_log_dev_available_kernel(void)  
  110. {  
  111.     if (g_log_status == kLogUninitialized) {  
  112.         if (access("/dev/"LOGGER_LOG_MAIN, W_OK) == 0)  
  113.             g_log_status = kLogAvailable;  
  114.         else  
  115.             g_log_status = kLogNotAvailable;  
  116.     }  
  117.   
  118.     return (g_log_status == kLogAvailable);  
  119. }  
  120.   
  121. int __android_log_dev_available(void)  
  122. {  
  123.     if (use_logd) {  
  124.         return __android_log_dev_available_logd();  
  125.     } else {  
  126.         return __android_log_dev_available_kernel();  
  127.     }  
  128. }  
  129.   
  130. /* log_init_lock assumed */  
  131. static int __write_to_log_initialize()  
  132. {  
  133.     int i, ret = 0;  
  134.   
  135. #if FAKE_LOG_DEVICE  
  136.     for (i = 0; i < LOG_ID_MAX; i++) {  
  137.         char buf[sizeof("/dev/log_system")];  
  138.         snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));  
  139.         log_fds_fake[i] = fakeLogOpen(buf, O_WRONLY);  
  140.     }  
  141. #else  
  142.     if (pstore_fd < 0) {  
  143.         pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));  
  144.     }  
  145.   
  146.     if (logd_fd < 0) {  
  147.         i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));  
  148.         if (i < 0) {  
  149.             ret = -errno;  
  150.         } else if (TEMP_FAILURE_RETRY(fcntl(i, F_SETFL, O_NONBLOCK)) < 0) {  
  151.             ret = -errno;  
  152.             close(i);  
  153.         } else {  
  154.             struct sockaddr_un un;  
  155.             memset(&un, 0, sizeof(struct sockaddr_un));  
  156.             un.sun_family = AF_UNIX;  
  157.             strcpy(un.sun_path, "/dev/socket/logdw");  
  158.   
  159.             if (TEMP_FAILURE_RETRY(connect(i, (struct sockaddr *)&un,  
  160.                                            sizeof(struct sockaddr_un))) < 0) {  
  161.                 ret = -errno;  
  162.                 close(i);  
  163.             } else {  
  164.                 logd_fd = i;  
  165.             }  
  166.         }  
  167.     }  
  168. #endif  
  169.   
  170.     return ret;  
  171. }  
  172.   
  173.   
  174. static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)  
  175. {  
  176.     ssize_t ret;  
  177. #if FAKE_LOG_DEVICE  
  178.     int log_fd;  
  179.   
  180.     if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {  
  181.         log_fd = log_fds_fake[(int)log_id];  
  182.     } else {  
  183.         return -EBADF;  
  184.     }  
  185.     do {  
  186.         ret = fakeLogWritev(log_fd, vec, nr);  
  187.         if (ret < 0) {  
  188.             ret = -errno;  
  189.         }  
  190.     } while (ret == -EINTR);  
  191. #else  
  192.     static const unsigned header_length = 2;  
  193.     struct iovec newVec[nr + header_length];  
  194.     android_log_header_t header;  
  195.     android_pmsg_log_header_t pmsg_header;  
  196.     struct timespec ts;  
  197.     size_t i, payload_size;  
  198.     static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */  
  199.     static pid_t last_pid = (pid_t) -1;  
  200.     static atomic_int_fast32_t dropped;  
  201.   
  202.     if (!nr) {  
  203.         return -EINVAL;  
  204.     }  
  205.   
  206.     if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */  
  207.         last_uid = getuid();  
  208.     }  
  209.     if (last_pid == (pid_t) -1) {  
  210.         last_pid = getpid();  
  211.     }  
  212.     /* 
  213.      *  struct { 
  214.      *      // what we provide to pstore 
  215.      *      android_pmsg_log_header_t pmsg_header; 
  216.      *      // what we provide to socket 
  217.      *      android_log_header_t header; 
  218.      *      // caller provides 
  219.      *      union { 
  220.      *          struct { 
  221.      *              char     prio; 
  222.      *              char     payload[]; 
  223.      *          } string; 
  224.      *          struct { 
  225.      *              uint32_t tag 
  226.      *              char     payload[]; 
  227.      *          } binary; 
  228.      *      }; 
  229.      *  }; 
  230.      */  
  231.   
  232.     clock_gettime(CLOCK_REALTIME, &ts);  
  233.   
  234.     pmsg_header.magic = LOGGER_MAGIC;  
  235.     pmsg_header.len = sizeof(pmsg_header) + sizeof(header);  
  236.     pmsg_header.uid = last_uid;  
  237.     pmsg_header.pid = last_pid;  
  238.   
  239.     header.tid = gettid();  
  240.     header.realtime.tv_sec = ts.tv_sec;  
  241.     header.realtime.tv_nsec = ts.tv_nsec;  
  242.   
  243.     newVec[0].iov_base   = (unsigned char *) &pmsg_header;  
  244.     newVec[0].iov_len    = sizeof(pmsg_header);  
  245.     newVec[1].iov_base   = (unsigned char *) &header;  
  246.     newVec[1].iov_len    = sizeof(header);  
  247.   
  248.     if (logd_fd > 0) {  
  249.         int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);  
  250.         if (snapshot) {  
  251.             android_log_event_int_t buffer;  
  252.   
  253.             header.id = LOG_ID_EVENTS;  
  254.             buffer.header.tag = htole32(LIBLOG_LOG_TAG);  
  255.             buffer.payload.type = EVENT_TYPE_INT;  
  256.             buffer.payload.data = htole32(snapshot);  
  257.   
  258.             newVec[2].iov_base = &buffer;  
  259.             newVec[2].iov_len  = sizeof(buffer);  
  260.   
  261.             ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2));  
  262.             if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {  
  263.                 atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);  
  264.             }  
  265.         }  
  266.     }  
  267.   
  268.     header.id = log_id;  
  269.   
  270.     for (payload_size = 0, i = header_length; i < nr + header_length; i++) {  
  271.         newVec[i].iov_base = vec[i - header_length].iov_base;  
  272.         payload_size += newVec[i].iov_len = vec[i - header_length].iov_len;  
  273.   
  274.         if (payload_size > LOGGER_ENTRY_MAX_PAYLOAD) {  
  275.             newVec[i].iov_len -= payload_size - LOGGER_ENTRY_MAX_PAYLOAD;  
  276.             if (newVec[i].iov_len) {  
  277.                 ++i;  
  278.             }  
  279.             payload_size = LOGGER_ENTRY_MAX_PAYLOAD;  
  280.             break;  
  281.         }  
  282.     }  
  283.     pmsg_header.len += payload_size;  
  284.   
  285.     if (pstore_fd >= 0) {  
  286.         TEMP_FAILURE_RETRY(writev(pstore_fd, newVec, i));  
  287.     }  
  288.   
  289.     if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */  
  290.         /* 
  291.          * ignore log messages we send to ourself (logd). 
  292.          * Such log messages are often generated by libraries we depend on 
  293.          * which use standard Android logging. 
  294.          */  
  295.         return 0;  
  296.     }  
  297.   
  298.     if (logd_fd < 0) {  
  299.         return -EBADF;  
  300.     }  
  301.   
  302.     /* 
  303.      * The write below could be lost, but will never block. 
  304.      * 
  305.      * To logd, we drop the pmsg_header 
  306.      * 
  307.      * ENOTCONN occurs if logd dies. 
  308.      * EAGAIN occurs if logd is overloaded. 
  309.      */  
  310.     ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));  
  311.     if (ret < 0) {  
  312.         ret = -errno;  
  313.         if (ret == -ENOTCONN) {  
  314. #if !defined(_WIN32)  
  315.             pthread_mutex_lock(&log_init_lock);  
  316. #endif  
  317.             close(logd_fd);  
  318.             logd_fd = -1;  
  319.             ret = __write_to_log_initialize();  
  320. #if !defined(_WIN32)  
  321.             pthread_mutex_unlock(&log_init_lock);  
  322. #endif  
  323.   
  324.             if (ret < 0) {  
  325.                 return ret;  
  326.             }  
  327.   
  328.             ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));  
  329.             if (ret < 0) {  
  330.                 ret = -errno;  
  331.             }  
  332.         }  
  333.     }  
  334.   
  335.     if (ret > (ssize_t)sizeof(header)) {  
  336.         ret -= sizeof(header);  
  337.     } else if (ret == -EAGAIN) {  
  338.         atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);  
  339.     }  
  340. #endif  
  341.   
  342.     return ret;  
  343. }  
  344.   
  345. #if FAKE_LOG_DEVICE  
  346. static const char *LOG_NAME[LOG_ID_MAX] = {  
  347.     [LOG_ID_MAIN] = "main",  
  348.     [LOG_ID_RADIO] = "radio",  
  349.     [LOG_ID_EVENTS] = "events",  
  350.     [LOG_ID_SYSTEM] = "system",  
  351.     [LOG_ID_CRASH] = "crash",  
  352.     [LOG_ID_KERNEL] = "kernel",  
  353. };  
  354.   
  355. const char *android_log_id_to_name(log_id_t log_id)  
  356. {  
  357.     if (log_id >= LOG_ID_MAX) {  
  358.         log_id = LOG_ID_MAIN;  
  359.     }  
  360.     return LOG_NAME[log_id];  
  361. }  
  362. #endif  
  363.   
  364. static int __write_to_log_init_logd(log_id_t log_id, struct iovec *vec, size_t nr)  
  365. {  
  366. #if !defined(_WIN32)  
  367.     pthread_mutex_lock(&log_init_lock);  
  368. #endif  
  369.   
  370.     if (write_to_log == __write_to_log_init) {  
  371.         int ret;  
  372.   
  373.         ret = __write_to_log_initialize();  
  374.         if (ret < 0) {  
  375. #if !defined(_WIN32)  
  376.             pthread_mutex_unlock(&log_init_lock);  
  377. #endif  
  378. #if (FAKE_LOG_DEVICE == 0)  
  379.             if (pstore_fd >= 0) {  
  380.                 __write_to_log_daemon(log_id, vec, nr);  
  381.             }  
  382. #endif  
  383.             return ret;  
  384.         }  
  385.   
  386.         write_to_log = __write_to_log_daemon;  
  387.     }  
  388.   
  389. #if !defined(_WIN32)  
  390.     pthread_mutex_unlock(&log_init_lock);  
  391. #endif  
  392.   
  393.     return write_to_log(log_id, vec, nr);  
  394. }  
  395.   
  396. static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused,  
  397.                                size_t nr __unused)  
  398. {  
  399.     return -1;  
  400. }  
  401.   
  402. static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)  
  403. {  
  404.     ssize_t ret;  
  405.     int log_fd;  
  406.   
  407.     if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {  
  408.         if (log_id == LOG_ID_CRASH) {  
  409.             log_id = LOG_ID_MAIN;  
  410.         }  
  411.         log_fd = log_fds_kernel[(int)log_id];  
  412.     } else {  
  413.         return -EBADF;  
  414.     }  
  415.   
  416.     do {  
  417.         ret = log_writev(log_fd, vec, nr);  
  418.         if (ret < 0) {  
  419.             ret = -errno;  
  420.         }  
  421.     } while (ret == -EINTR);  
  422.   
  423.     return ret;  
  424. }  
  425.   
  426. static int __write_to_log_init_kernel(log_id_t log_id, struct iovec *vec, size_t nr)  
  427. {  
  428.     pthread_mutex_lock(&log_init_lock);  
  429.   
  430.     if (write_to_log == __write_to_log_init) {  
  431.         log_fds_kernel[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);  
  432.         log_fds_kernel[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);  
  433.         log_fds_kernel[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);  
  434.         log_fds_kernel[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);  
  435.   
  436.         write_to_log = __write_to_log_kernel;  
  437.   
  438.         if (log_fds_kernel[LOG_ID_MAIN] < 0 || log_fds_kernel[LOG_ID_RADIO] < 0 ||  
  439.                 log_fds_kernel[LOG_ID_EVENTS] < 0) {  
  440.             log_close(log_fds_kernel[LOG_ID_MAIN]);  
  441.             log_close(log_fds_kernel[LOG_ID_RADIO]);  
  442.             log_close(log_fds_kernel[LOG_ID_EVENTS]);  
  443.             log_fds_kernel[LOG_ID_MAIN] = -1;  
  444.             log_fds_kernel[LOG_ID_RADIO] = -1;  
  445.             log_fds_kernel[LOG_ID_EVENTS] = -1;  
  446.             write_to_log = __write_to_log_null;  
  447.         }  
  448.   
  449.         if (log_fds_kernel[LOG_ID_SYSTEM] < 0) {  
  450.             log_fds_kernel[LOG_ID_SYSTEM] = log_fds_kernel[LOG_ID_MAIN];  
  451.         }  
  452.     }  
  453.   
  454.     pthread_mutex_unlock(&log_init_lock);  
  455.   
  456.     return write_to_log(log_id, vec, nr);  
  457. }  
  458.   
  459. static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) {  
  460. #if (FAKE_LOG_DEVICE == 0)  
  461.     int fd;  
  462.     fd = open("system/etc/disable_logd", O_RDONLY);//是否有disable_logd文件  
  463.     if (fd > 0) {  
  464.         use_logd = 0;  
  465.         close(fd);  
  466.     }  
  467. #endif  
  468.   
  469.     if(use_logd) {  
  470.         return __write_to_log_init_logd(log_id, vec, nr);  
  471.     } else {  
  472.         return __write_to_log_init_kernel(log_id, vec, nr);  
  473.     }  
  474. }  
  475.   
  476. int __android_log_write(int prio, const char *tag, const char *msg)  
  477. {  
  478.     return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);  
  479. }  
  480.   
  481. int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)  
  482. {  
  483.     struct iovec vec[3];  
  484.     char tmp_tag[32];  
  485.   
  486.     if (!tag)  
  487.         tag = "";  
  488.   
  489.     /* XXX: This needs to go! */  
  490.     if ((bufID != LOG_ID_RADIO) &&  
  491.          (!strcmp(tag, "HTC_RIL") ||  
  492.         !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */  
  493.         !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */  
  494.         !strcmp(tag, "AT") ||  
  495.         !strcmp(tag, "GSM") ||  
  496.         !strcmp(tag, "STK") ||  
  497.         !strcmp(tag, "CDMA") ||  
  498.         !strcmp(tag, "PHONE") ||  
  499.         !strcmp(tag, "SMS"))) {  
  500.             bufID = LOG_ID_RADIO;  
  501.             /* Inform third party apps/ril/radio.. to use Rlog or RLOG */  
  502.             snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);  
  503.             tag = tmp_tag;  
  504.     }  
  505.   
  506. #if __BIONIC__  
  507.     if (prio == ANDROID_LOG_FATAL) {  
  508.         android_set_abort_message(msg);  
  509.     }  
  510. #endif  
  511.   
  512.     vec[0].iov_base   = (unsigned char *) &prio;  
  513.     vec[0].iov_len    = 1;  
  514.     vec[1].iov_base   = (void *) tag;  
  515.     vec[1].iov_len    = strlen(tag) + 1;  
  516.     vec[2].iov_base   = (void *) msg;  
  517.     vec[2].iov_len    = strlen(msg) + 1;  
  518.   
  519.     return write_to_log(bufID, vec, 3);  
  520. }  
  521.   
  522. int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)  
  523. {  
  524.     char buf[LOG_BUF_SIZE];  
  525.   
  526.     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  527.   
  528.     return __android_log_write(prio, tag, buf);  
  529. }  
  530.   
  531. int __android_log_print(int prio, const char *tag, const char *fmt, ...)  
  532. {  
  533.     va_list ap;  
  534.     char buf[LOG_BUF_SIZE];  
  535.   
  536.     va_start(ap, fmt);  
  537.     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  538.     va_end(ap);  
  539.   
  540.     return __android_log_write(prio, tag, buf);  
  541. }  
  542.   
  543. int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)  
  544. {  
  545.     va_list ap;  
  546.     char buf[LOG_BUF_SIZE];  
  547.   
  548.     va_start(ap, fmt);  
  549.     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  550.     va_end(ap);  
  551.   
  552.     return __android_log_buf_write(bufID, prio, tag, buf);  
  553. }  
  554.   
  555. void __android_log_assert(const char *cond, const char *tag,  
  556.                           const char *fmt, ...)  
  557. {  
  558.     char buf[LOG_BUF_SIZE];  
  559.   
  560.     if (fmt) {  
  561.         va_list ap;  
  562.         va_start(ap, fmt);  
  563.         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  564.         va_end(ap);  
  565.     } else {  
  566.         /* Msg not provided, log condition.  N.B. Do not use cond directly as 
  567.          * format string as it could contain spurious '%' syntax (e.g. 
  568.          * "%d" in "blocks%devs == 0"). 
  569.          */  
  570.         if (cond)  
  571.             snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);  
  572.         else  
  573.             strcpy(buf, "Unspecified assertion failed");  
  574.     }  
  575.   
  576.     __android_log_write(ANDROID_LOG_FATAL, tag, buf);  
  577.     abort(); /* abort so we have a chance to debug the situation */  
  578.     /* NOTREACHED */  
  579. }  
  580.   
  581. int __android_log_bwrite(int32_t tag, const void *payload, size_t len)  
  582. {  
  583.     struct iovec vec[2];  
  584.   
  585.     vec[0].iov_base = &tag;  
  586.     vec[0].iov_len = sizeof(tag);  
  587.     vec[1].iov_base = (void*)payload;  
  588.     vec[1].iov_len = len;  
  589.   
  590.     return write_to_log(LOG_ID_EVENTS, vec, 2);  
  591. }  
  592.   
  593. /* 
  594.  * Like __android_log_bwrite, but takes the type as well.  Doesn't work 
  595.  * for the general case where we're generating lists of stuff, but very 
  596.  * handy if we just want to dump an integer into the log. 
  597.  */  
  598. int __android_log_btwrite(int32_t tag, char type, const void *payload,  
  599.                           size_t len)  
  600. {  
  601.     struct iovec vec[3];  
  602.   
  603.     vec[0].iov_base = &tag;  
  604.     vec[0].iov_len = sizeof(tag);  
  605.     vec[1].iov_base = &type;  
  606.     vec[1].iov_len = sizeof(type);  
  607.     vec[2].iov_base = (void*)payload;  
  608.     vec[2].iov_len = len;  
  609.   
  610.     return write_to_log(LOG_ID_EVENTS, vec, 3);  
  611. }  
  612.   
  613. /* 
  614.  * Like __android_log_bwrite, but used for writing strings to the 
  615.  * event log. 
  616.  */  
  617. int __android_log_bswrite(int32_t tag, const char *payload)  
  618. {  
  619.     struct iovec vec[4];  
  620.     char type = EVENT_TYPE_STRING;  
  621.     uint32_t len = strlen(payload);  
  622.   
  623.     vec[0].iov_base = &tag;  
  624.     vec[0].iov_len = sizeof(tag);  
  625.     vec[1].iov_base = &type;  
  626.     vec[1].iov_len = sizeof(type);  
  627.     vec[2].iov_base = &len;  
  628.     vec[2].iov_len = sizeof(len);  
  629.     vec[3].iov_base = (void*)payload;  
  630.     vec[3].iov_len = len;  
  631.   
  632.     return write_to_log(LOG_ID_EVENTS, vec, 4);  
  633. }  

另外一个就是log_read_common.c文件,将log_read.c和log_read_kern.c合并。这样文件稍微复杂一点,因为在log_read.c和log_read_kern.c中都使用了struct logger_list 和struct logger结构体而且不一样,这样我们将共同部分做了一个基类的struct logger_list 和struct logger结构体。而在合并文件中定义了struct logger_list_logd struct logger_list_kernel结构体,将其基类放在第一个变量base中。而使用指针时,对外返回的指针强制转成基类,进入的指针强制转到相关的子类。因为基类的数据结构在子类结构体中是第一个,因此子类指针强转成父类,也是能正确调用到父类的变量的。

还有我们也是用use_logd这个全局变量来控制log机制的,并且定义了一个对外的函数set_uselogd. 因为使用read这块是在logcat进程中使用的,我们需要在logcat中调用。

[cpp]  view plain  copy
  1. /* 
  2. ** Copyright 2013-2014, The Android Open Source Project 
  3. ** 
  4. ** Licensed under the Apache License, Version 2.0 (the "License"); 
  5. ** you may not use this file except in compliance with the License. 
  6. ** You may obtain a copy of the License at 
  7. ** 
  8. **     http://www.apache.org/licenses/LICENSE-2.0 
  9. ** 
  10. ** Unless required by applicable law or agreed to in writing, software 
  11. ** distributed under the License is distributed on an "AS IS" BASIS, 
  12. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13. ** See the License for the specific language governing permissions and 
  14. ** limitations under the License. 
  15. */  
  16. #define _GNU_SOURCE /* asprintf for x86 host */  
  17. #include   
  18. #include   
  19. #include   
  20. #include   
  21. #include   
  22. #include   
  23. #include   
  24. #define NOMINMAX /* for windows to suppress definition of min in stdlib.h */  
  25. #include   
  26. #include   
  27. #include   
  28. #include   
  29. #include   
  30. #include   
  31. #include   
  32.   
  33. #include   
  34. #include   
  35. #include   
  36. #include   
  37. #include   
  38. #include   
  39.   
  40. #include   
  41.   
  42. #define __LOGGERIO     0xAE  
  43.   
  44. #define LOGGER_GET_LOG_BUF_SIZE    _IO(__LOGGERIO, 1) /* size of log */  
  45. #define LOGGER_GET_LOG_LEN         _IO(__LOGGERIO, 2) /* used log len */  
  46. #define LOGGER_GET_NEXT_ENTRY_LEN  _IO(__LOGGERIO, 3) /* next entry len */  
  47. #define LOGGER_FLUSH_LOG           _IO(__LOGGERIO, 4) /* flush log */  
  48. #define LOGGER_GET_VERSION         _IO(__LOGGERIO, 5) /* abi version */  
  49. #define LOGGER_SET_VERSION         _IO(__LOGGERIO, 6) /* abi version */  
  50.   
  51. #define LOG_FILE_DIR "/dev/log/"  
  52.   
  53. /* timeout in milliseconds */  
  54. #define LOG_TIMEOUT_FLUSH 5  
  55. #define LOG_TIMEOUT_NEVER -1  
  56.   
  57. /* branchless on many architectures. */  
  58. #define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))  
  59.   
  60. #if (defined(USE_MINGW) || defined(HAVE_WINSOCK))  
  61. #define WEAK static  
  62. #else  
  63. #define WEAK __attribute__((weak))  
  64. #endif  
  65. #ifndef __unused  
  66. #define __unused __attribute__((unused))  
  67. #endif  
  68.   
  69. static int8_t use_logd = 1;//版本控制  
  70.   
  71. void set_uselogd(int8_t uselogd) {//对外函数  
  72.     use_logd = uselogd;  
  73. }  
  74.   
  75. /* Private copy of ../libcutils/socket_local_client.c prevent library loops */  
  76.   
  77. #ifdef HAVE_WINSOCK  
  78.   
  79. int WEAK socket_local_client(const char *name, int namespaceId, int type)  
  80. {  
  81.     errno = ENOSYS;  
  82.     return -ENOSYS;  
  83. }  
  84.   
  85. #else /* !HAVE_WINSOCK */  
  86.   
  87. #include   
  88. #include   
  89. #include   
  90. #include   
  91.   
  92. /* Private copy of ../libcutils/socket_local.h prevent library loops */  
  93. #define FILESYSTEM_SOCKET_PREFIX "/tmp/"  
  94. #define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"  
  95. /* End of ../libcutils/socket_local.h */  
  96.   
  97. #define LISTEN_BACKLOG 4  
  98.   
  99. /* Documented in header file. */  
  100. int WEAK socket_make_sockaddr_un(const char *name, int namespaceId,  
  101.                                  struct sockaddr_un *p_addr, socklen_t *alen)  
  102. {  
  103.     memset (p_addr, 0, sizeof (*p_addr));  
  104.     size_t namelen;  
  105.   
  106.     switch (namespaceId) {  
  107.     case ANDROID_SOCKET_NAMESPACE_ABSTRACT:  
  108. #if defined(__linux__)  
  109.         namelen  = strlen(name);  
  110.   
  111.         /* Test with length +1 for the *initial* '\0'. */  
  112.         if ((namelen + 1) > sizeof(p_addr->sun_path)) {  
  113.             goto error;  
  114.         }  
  115.   
  116.         /* 
  117.          * Note: The path in this case is *not* supposed to be 
  118.          * '\0'-terminated. ("man 7 unix" for the gory details.) 
  119.          */  
  120.   
  121.         p_addr->sun_path[0] = 0;  
  122.         memcpy(p_addr->sun_path + 1, name, namelen);  
  123. #else  
  124.         /* this OS doesn't have the Linux abstract namespace */  
  125.   
  126.         namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);  
  127.         /* unix_path_max appears to be missing on linux */  
  128.         if (namelen > sizeof(*p_addr)  
  129.                 - offsetof(struct sockaddr_un, sun_path) - 1) {  
  130.             goto error;  
  131.         }  
  132.   
  133.         strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);  
  134.         strcat(p_addr->sun_path, name);  
  135. #endif  
  136.         break;  
  137.   
  138.     case ANDROID_SOCKET_NAMESPACE_RESERVED:  
  139.         namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);  
  140.         /* unix_path_max appears to be missing on linux */  
  141.         if (namelen > sizeof(*p_addr)  
  142.                 - offsetof(struct sockaddr_un, sun_path) - 1) {  
  143.             goto error;  
  144.         }  
  145.   
  146.         strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);  
  147.         strcat(p_addr->sun_path, name);  
  148.         break;  
  149.   
  150.     case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:  
  151.         namelen = strlen(name);  
  152.         /* unix_path_max appears to be missing on linux */  
  153.         if (namelen > sizeof(*p_addr)  
  154.                 - offsetof(struct sockaddr_un, sun_path) - 1) {  
  155.             goto error;  
  156.         }  
  157.   
  158.         strcpy(p_addr->sun_path, name);  
  159.         break;  
  160.   
  161.     default:  
  162.         /* invalid namespace id */  
  163.         return -1;  
  164.     }  
  165.   
  166.     p_addr->sun_family = AF_LOCAL;  
  167.     *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;  
  168.     return 0;  
  169. error:  
  170.     return -1;  
  171. }  
  172.   
  173. /** 
  174.  * connect to peer named "name" on fd 
  175.  * returns same fd or -1 on error. 
  176.  * fd is not closed on error. that's your job. 
  177.  * 
  178.  * Used by AndroidSocketImpl 
  179.  */  
  180. int WEAK socket_local_client_connect(int fd, const char *name, int namespaceId,  
  181.                                      int type __unused)  
  182. {  
  183.     struct sockaddr_un addr;  
  184.     socklen_t alen;  
  185.     int err;  
  186.   
  187.     err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);  
  188.   
  189.     if (err < 0) {  
  190.         goto error;  
  191.     }  
  192.   
  193.     if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {  
  194.         goto error;  
  195.     }  
  196.   
  197.     return fd;  
  198.   
  199. error:  
  200.     return -1;  
  201. }  
  202.   
  203. /** 
  204.  * connect to peer named "name" 
  205.  * returns fd or -1 on error 
  206.  */  
  207. int WEAK socket_local_client(const char *name, int namespaceId, int type)  
  208. {  
  209.     int s;  
  210.   
  211.     s = socket(AF_LOCAL, type, 0);  
  212.     if(s < 0) return -1;  
  213.   
  214.     if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {  
  215.         close(s);  
  216.         return -1;  
  217.     }  
  218.   
  219.     return s;  
  220. }  
  221.   
  222. #endif /* !HAVE_WINSOCK */  
  223. /* End of ../libcutils/socket_local_client.c */  
  224.   
  225. #define logger_for_each(logger, logger_list) \  
  226.     for (logger = node_to_item((logger_list)->node.next, struct logger, node); \  
  227.          logger != node_to_item(&(logger_list)->node, struct logger, node); \  
  228.          logger = node_to_item((logger)->node.next, struct logger, node))  
  229.   
  230. #ifndef __unused  
  231. #define __unused __attribute__((unused))  
  232. #endif  
  233.   
  234. /* In the future, we would like to make this list extensible */  
  235. static const char *LOG_NAME[LOG_ID_MAX] = {  
  236.     [LOG_ID_MAIN] = "main",  
  237.     [LOG_ID_RADIO] = "radio",  
  238.     [LOG_ID_EVENTS] = "events",  
  239.     [LOG_ID_SYSTEM] = "system",  
  240.     [LOG_ID_CRASH] = "crash",  
  241.     [LOG_ID_KERNEL] = "kernel",  
  242. };  
  243.   
  244. const char *android_log_id_to_name(log_id_t log_id)  
  245. {  
  246.     if (log_id >= LOG_ID_MAX) {  
  247.         log_id = LOG_ID_MAIN;  
  248.     }  
  249.     return LOG_NAME[log_id];  
  250. }  
  251.   
  252. static int accessmode(int mode)  
  253. {  
  254.     if ((mode & ANDROID_LOG_ACCMODE) == ANDROID_LOG_WRONLY) {  
  255.         return W_OK;  
  256.     }  
  257.     if ((mode & ANDROID_LOG_ACCMODE) == ANDROID_LOG_RDWR) {  
  258.         return R_OK | W_OK;  
  259.     }  
  260.     return R_OK;  
  261. }  
  262.   
  263. /* repeated fragment */

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. android 资源文件的使用说明
  6. Android(安卓)Studio中JNI程序的单步调试和日志打印
  7. Android实践--apk反编译
  8. 详解Android使用OKHttp3实现下载(断点续传、显示进度)
  9. Android如何开机自动执行脚本文件

随机推荐

  1. android 柱状图(带动画的)
  2. Google I/O 2011, Android Accelerated R
  3. Android官方文档翻译 三 1.1Creating an
  4. android > SMS 短信数据库访问
  5. android jpush 极光推送
  6. android Ongoing
  7. Android - under the hood
  8. android创建通知栏(java版)
  9. Android学习笔记(7)————Android中的
  10. android电量状态获取