android log丢失(二)使用and4.4log kernel机制

来源:互联网 发布:对网络教育的看法作文 编辑:程序博客网 时间:2024/05/18 00:09

在之前一篇博客我们是分析了logd丢失的原因,而且从增大logd缓冲区大小,以及增加白名单的方式临时解决调试问题。

这里我们就如何回到android4.4的log机制来分析。

当然还有一种方式,在android4.4的时候是不使用logd的机制的。使用的是往内存文件系统里面写log,写入dev/log/main  dev/log/radio等log。我们可以改回之前的模式。需要打几个补丁,这样就不会有丢失log的情况(不会有类似chatty的log)。

kernel的话我们可以看看dev/log目录下是否有main raidio等节点。如果有说明kernel是支持的,不需要打补丁了。只需改动system/core/liblog目录  以及修改板卡目录boardconfig.mk 还有selinux的权限。具体如下:

1. system/core/liblog补丁

地址:https://source.codeaurora.org/quic/la/platform/system/core/commit/?id=1b078a205c4ba34e2eaf5c5b248967ea4c08fb2c

[html] view plain copy
  1. From 1b078a205c4ba34e2eaf5c5b248967ea4c08fb2c Mon Sep 17 00:00:00 2001  
  2. From: Maria Yu <aiquny@codeaurora.org>  
  3. Date: Wed, 23 Mar 2016 15:35:34 +0800  
  4. Subject: liblog: Fix compile error for using legacy kernel logger driver  
  5.   
  6. Add log_event_write.c into liblog_sources file when using legacy  
  7. kernel logger driver. Add socket_local_client API in log_read_kern.  
  8. Fix the BIONIC define missing in logd_write_kern.  
  9.   
  10. CRs-Fixed: 949708  
  11. Change-Id: If7a85e1d19fdd22581b6eb87096b39c2a700297e  
  12. ---  
  13.  liblog/Android.mk        |   2 +-  
  14.  liblog/log_read_kern.c   | 169 +++++++++++++++++++++++++++++++++++++++++++++--  
  15.  liblog/logd_write_kern.c |   6 +-  
  16.  3 files changed, 170 insertions(+), 7 deletions(-)  
  17.   
  18. diff --git a/liblog/Android.mk b/liblog/Android.mk  
  19. index 115dd79..1f113c5 100644  
  20. --- a/liblog/Android.mk  
  21. +++ b/liblog/Android.mk  
  22. @@ -27,7 +27,7 @@  
  23.  ifneq ($(TARGET_USES_LOGD),false)  
  24.  liblog_sources :logd_write.c log_event_write.c  
  25.  else  
  26. -liblog_sources :logd_write_kern.c  
  27. +liblog_sources :logd_write_kern.c log_event_write.c  
  28.  endif  
  29.    
  30.  # some files must not be compiled when building against Mingw  
  31. diff --git a/liblog/log_read_kern.c b/liblog/log_read_kern.c  
  32. index 69b405c..b1b9a26 100644  
  33. --- a/liblog/log_read_kern.c  
  34. +++ b/liblog/log_read_kern.c  
  35. @@ -1,5 +1,5 @@  
  36.  /*  
  37. -** Copyright 2013-2014, The Android Open Source Project  
  38. +** Copyright 2013-2014,2016 The Android Open Source Project  
  39.  **  
  40.  ** Licensed under the Apache License, Version 2.0 (the "License");  
  41.  ** you may not use this file except in compliance with the License.  
  42. @@ -27,6 +27,7 @@  
  43.  #include <cutils/list.h>  
  44.  #include <log/log.h>  
  45.  #include <log/logger.h>  
  46. +#include <cutils/sockets.h>  
  47.    
  48.  #define __LOGGERIO     0xAE  
  49.    
  50. @@ -37,16 +38,174 @@  
  51.  #define LOGGER_GET_VERSION         _IO(__LOGGERIO, 5) /* abi version */  
  52.  #define LOGGER_SET_VERSION         _IO(__LOGGERIO, 6) /* abi version */  
  53.    
  54. -typedef char bool;  
  55. -#define false (const bool)0  
  56. -#define true (const bool)1  
  57. -  
  58.  #define LOG_FILE_DIR "/dev/log/"  
  59.    
  60.  /* timeout in milliseconds */  
  61.  #define LOG_TIMEOUT_FLUSH 5  
  62.  #define LOG_TIMEOUT_NEVER -1  
  63.    
  64. +/* branchless on many architectures. */  
  65. +#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))  
  66. +  
  67. +#if (defined(USE_MINGW) || defined(HAVE_WINSOCK))  
  68. +#define WEAK static  
  69. +#else  
  70. +#define WEAK __attribute__((weak))  
  71. +#endif  
  72. +#ifndef __unused  
  73. +#define __unused __attribute__((unused))  
  74. +#endif  
  75. +  
  76. +/* Private copy of ../libcutils/socket_local_client.c prevent library loops */  
  77. +  
  78. +#ifdef HAVE_WINSOCK  
  79. +  
  80. +int WEAK socket_local_client(const char *name, int namespaceId, int type)  
  81. +{  
  82. +    errno = ENOSYS;  
  83. +    return -ENOSYS;  
  84. +}  
  85. +  
  86. +#else /* !HAVE_WINSOCK */  
  87. +  
  88. +#include <sys/socket.h>  
  89. +#include <sys/un.h>  
  90. +#include <sys/select.h>  
  91. +#include <sys/types.h>  
  92. +  
  93. +/* Private copy of ../libcutils/socket_local.h prevent library loops */  
  94. +#define FILESYSTEM_SOCKET_PREFIX "/tmp/"  
  95. +#define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"  
  96. +/* End of ../libcutils/socket_local.h */  
  97. +  
  98. +#define LISTEN_BACKLOG 4  
  99. +  
  100. +/* Documented in header file. */  
  101. +int WEAK socket_make_sockaddr_un(const char *name, int namespaceId,  
  102. +                                 struct sockaddr_un *p_addr, socklen_t *alen)  
  103. +{  
  104. +    memset (p_addr, 0, sizeof (*p_addr));  
  105. +    size_t namelen;  
  106. +  
  107. +    switch (namespaceId) {  
  108. +    case ANDROID_SOCKET_NAMESPACE_ABSTRACT:  
  109. +#if defined(__linux__)  
  110. +        namelen  = strlen(name);  
  111. +  
  112. +        /* Test with length +1 for the *initial* '\0'. */  
  113. +        if ((namelen + 1) > sizeof(p_addr->sun_path)) {  
  114. +            goto error;  
  115. +        }  
  116. +  
  117. +        /*  
  118. +         * Note: The path in this case is *not* supposed to be  
  119. +         * '\0'-terminated. ("man 7 unix" for the gory details.)  
  120. +         */  
  121. +  
  122. +        p_addr->sun_path[0] = 0;  
  123. +        memcpy(p_addr->sun_path + 1, name, namelen);  
  124. +#else  
  125. +        /* this OS doesn't have the Linux abstract namespace */  
  126. +  
  127. +        namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);  
  128. +        /* unix_path_max appears to be missing on linux */  
  129. +        if (namelen > sizeof(*p_addr)  
  130. +                - offsetof(struct sockaddr_un, sun_path) - 1) {  
  131. +            goto error;  
  132. +        }  
  133. +  
  134. +        strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);  
  135. +        strcat(p_addr->sun_path, name);  
  136. +#endif  
  137. +        break;  
  138. +  
  139. +    case ANDROID_SOCKET_NAMESPACE_RESERVED:  
  140. +        namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);  
  141. +        /* unix_path_max appears to be missing on linux */  
  142. +        if (namelen > sizeof(*p_addr)  
  143. +                - offsetof(struct sockaddr_un, sun_path) - 1) {  
  144. +            goto error;  
  145. +        }  
  146. +  
  147. +        strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);  
  148. +        strcat(p_addr->sun_path, name);  
  149. +        break;  
  150. +  
  151. +    case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:  
  152. +        namelen = strlen(name);  
  153. +        /* unix_path_max appears to be missing on linux */  
  154. +        if (namelen > sizeof(*p_addr)  
  155. +                - offsetof(struct sockaddr_un, sun_path) - 1) {  
  156. +            goto error;  
  157. +        }  
  158. +  
  159. +        strcpy(p_addr->sun_path, name);  
  160. +        break;  
  161. +  
  162. +    default:  
  163. +        /* invalid namespace id */  
  164. +        return -1;  
  165. +    }  
  166. +  
  167. +    p_addr->sun_family = AF_LOCAL;  
  168. +    *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;  
  169. +    return 0;  
  170. +error:  
  171. +    return -1;  
  172. +}  
  173. +  
  174. +/**  
  175. + * connect to peer named "name" on fd  
  176. + * returns same fd or -1 on error.  
  177. + * fd is not closed on error. that's your job.  
  178. + *  
  179. + * Used by AndroidSocketImpl  
  180. + */  
  181. +int WEAK socket_local_client_connect(int fd, const char *name, int namespaceId,  
  182. +                                     int type __unused)  
  183. +{  
  184. +    struct sockaddr_un addr;  
  185. +    socklen_t alen;  
  186. +    int err;  
  187. +  
  188. +    err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);  
  189. +  
  190. +    if (err < 0) {  
  191. +        goto error;  
  192. +    }  
  193. +  
  194. +    if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {  
  195. +        goto error;  
  196. +    }  
  197. +  
  198. +    return fd;  
  199. +  
  200. +error:  
  201. +    return -1;  
  202. +}  
  203. +  
  204. +/**  
  205. + * connect to peer named "name"  
  206. + * returns fd or -1 on error  
  207. + */  
  208. +int WEAK socket_local_client(const char *name, int namespaceId, int type)  
  209. +{  
  210. +    int s;  
  211. +  
  212. +    s = socket(AF_LOCAL, type, 0);  
  213. +    if(s < 0) return -1;  
  214. +  
  215. +    if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {  
  216. +        close(s);  
  217. +        return -1;  
  218. +    }  
  219. +  
  220. +    return s;  
  221. +}  
  222. +  
  223. +#endif /* !HAVE_WINSOCK */  
  224. +/* End of ../libcutils/socket_local_client.c */  
  225. +  
  226.  #define logger_for_each(logger, logger_list) \  
  227.      for (logger = node_to_item((logger_list)->node.next, struct logger, node); \  
  228.           logger != node_to_item(&(logger_list)->node, struct logger, node); \  
  229. diff --git a/liblog/logd_write_kern.c b/liblog/logd_write_kern.c  
  230. index 8742b34..bddfbdd 100644  
  231. --- a/liblog/logd_write_kern.c  
  232. +++ b/liblog/logd_write_kern.c  
  233. @@ -1,5 +1,5 @@  
  234.  /*  
  235. - * Copyright (C) 2007-2014 The Android Open Source Project  
  236. + * Copyright (C) 2007-2014,2016 The Android Open Source Project  
  237.   *  
  238.   * Licensed under the Apache License, Version 2.0 (the "License");  
  239.   * you may not use this file except in compliance with the License.  
  240. @@ -26,7 +26,9 @@  
  241.  #include <time.h>  
  242.  #include <unistd.h>  
  243.    
  244. +#ifdef __BIONIC__  
  245.  #include <android/set_abort_message.h>  
  246. +#endif  
  247.    
  248.  #include <log/log.h>  
  249.  #include <log/logd.h>  
  250. @@ -167,9 +169,11 @@ int __android_log_buf_write(int bufID, int prio, const char *tag, const char *ms  
  251.              tag = tmp_tag;  
  252.      }  
  253.    
  254. +#ifdef __BIONIC__  
  255.      if (prio == ANDROID_LOG_FATAL) {  
  256.          android_set_abort_message(msg);  
  257.      }  
  258. +#endif  
  259.    
  260.      vec[0].iov_base   = (unsigned char *) &prio;  
  261.      vec[0].iov_len    = 1;  
  262. --   
  263. cgit v1.1  


2. selinux权限

加上domain对log_device的读写权限

[html] view plain copy
  1. diff --git a/domain.te b/domain.te  
  2. index 0f6c6da..4e0f541 100644  
  3. --- a/domain.te  
  4. +++ b/domain.te  
  5. @@ -88,6 +88,8 @@ allow domain null_device:chr_file rw_file_perms;  
  6. allow domain zero_device:chr_file rw_file_perms;  
  7. allow domain ashmem_device:chr_file rw_file_perms;  
  8. allow domain binder_device:chr_file rw_file_perms;  
  9. +allow domain log_device:dir search;  
  10. +allow domain log_device:chr_file rw_file_perms;  
  11. allow domain ptmx_device:chr_file rw_file_perms;  
  12. allow domain alarm_device:chr_file r_file_perms;  
  13. allow domain urandom_device:chr_file rw_file_perms;  


3. 去除logd的编译

只要在所编译版本的BoardConfig.mk中加入TARGET_USES_LOGD := false


4. kernel相关补丁

kernel部分如果没有合入补丁的话:

kernel补丁:
https://us.codeaurora.org/cgit/quic/la/kernel/msm-3.18/commit/?id=
5ec14761ae4f9e0c65519a6d954da0a08f59fa80
https://us.codeaurora.org/cgit/quic/la/kernel/msm-3.18/commit/?id=
1813ebe46a4d61423be3c121484f298abdbaf86d

kernel的kconfig:
在kernel的kConfig文件中加上CONFIG_ANDROID_LOGGER=y

5. 后续

这样我们就可以回到android4.4的log机制,但是常规我们还是使用现在logd的机制,因为这样应该更节省内存开销会用户更加友好,而如果我们平时开发遇到丢失log很严重的问题就要重新烧版本比较麻烦,因此我考虑做一种可以动态切换的机制。


原文地址: http://blog.csdn.net/kc58236582/article/details/72276041

原创粉丝点击