~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_CN/dev-tools/kcov.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/translations/zh_CN/dev-tools/kcov.rst (Version linux-6.12-rc7) and /Documentation/translations/zh_CN/dev-tools/kcov.rst (Version linux-5.17.15)


  1 .. SPDX-License-Identifier: GPL-2.0               
  2                                                   
  3 .. include:: ../disclaimer-zh_CN.rst              
  4                                                   
  5 :Original: Documentation/dev-tools/kcov.rst       
  6 :Translator: 刘浩阳 Haoyang Liu <tttturtleru    
  7                                                   
  8 KCOV: 用于模糊测试的代码覆盖率        
  9 ==============================                    
 10                                                   
 11 KCOV 以一种适用于覆盖率引导的模    
 12 一个正在运行的内核的覆盖率数据    
 13 于任务启用的,因此 KCOV 可以精确    
 14                                                   
 15 要注意的是 KCOV 不是为了收集尽可    
 16 ,这是系统调用输入的函数。为了    
 17 覆盖率收集被启用,见下文)以及    
 18                                                   
 19 除了收集代码覆盖率,KCOV 还收集    
 20 查看详细信息。                             
 21                                                   
 22 除了从系统调用处理器收集覆盖率    
 23 被标注的部分收集覆盖率。见 "远    
 24                                                   
 25 先决条件                                      
 26 --------                                          
 27                                                   
 28 KCOV 依赖编译器插桩,要求 GCC 6.1.0     
 29                                                   
 30 收集操作数比较的覆盖率需要 GCC 8+    
 31                                                   
 32 为了启用 KCOV,需要使用如下参数    
 33                                                   
 34         CONFIG_KCOV=y                             
 35                                                   
 36 为了启用操作数比较覆盖率的收集    
 37                                                   
 38     CONFIG_KCOV_ENABLE_COMPARISONS=y              
 39                                                   
 40 覆盖率数据只会在调试文件系统被    
 41                                                   
 42         mount -t debugfs none /sys/kernel/debu    
 43                                                   
 44 覆盖率收集                                   
 45 ----------                                        
 46                                                   
 47 下面的程序演示了如何使用 KCOV 在    
 48                                                   
 49 .. code-block:: c                                 
 50                                                   
 51     #include <stdio.h>                            
 52     #include <stddef.h>                           
 53     #include <stdint.h>                           
 54     #include <stdlib.h>                           
 55     #include <sys/types.h>                        
 56     #include <sys/stat.h>                         
 57     #include <sys/ioctl.h>                        
 58     #include <sys/mman.h>                         
 59     #include <unistd.h>                           
 60     #include <fcntl.h>                            
 61     #include <linux/types.h>                      
 62                                                   
 63     #define KCOV_INIT_TRACE                       
 64     #define KCOV_ENABLE                 _IO('c    
 65     #define KCOV_DISABLE                          
 66     #define COVER_SIZE                  (64<<1    
 67                                                   
 68     #define KCOV_TRACE_PC  0                      
 69     #define KCOV_TRACE_CMP 1                      
 70                                                   
 71     int main(int argc, char **argv)               
 72     {                                             
 73         int fd;                                   
 74         unsigned long *cover, n, i;               
 75                                                   
 76         /* 单个文件描述符允许            
 77          * 在单线程上收集覆盖率。      
 78          */                                       
 79         fd = open("/sys/kernel/debug/kcov", O_    
 80         if (fd == -1)                             
 81                 perror("open"), exit(1);          
 82         /* 设置跟踪模式和跟踪大小    
 83         if (ioctl(fd, KCOV_INIT_TRACE, COVER_S    
 84                 perror("ioctl"), exit(1);         
 85         /* 映射内核空间和用户空间    
 86         cover = (unsigned long*)mmap(NULL, COV    
 87                                      PROT_READ    
 88         if ((void*)cover == MAP_FAILED)           
 89                 perror("mmap"), exit(1);          
 90         /* 在当前线程中启用覆盖率    
 91         if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_    
 92                 perror("ioctl"), exit(1);         
 93         /* 在调用 ioctl() 之后重置覆    
 94         __atomic_store_n(&cover[0], 0, __ATOMI    
 95         /* 调用目标系统调用。 */         
 96         read(-1, NULL, 0);                        
 97         /* 读取收集到的 PC 的数目。     
 98         n = __atomic_load_n(&cover[0], __ATOMI    
 99         for (i = 0; i < n; i++)                   
100                 printf("0x%lx\n", cover[i + 1]    
101         /* 在当前线程上禁用覆盖率    
102          * 可以在其他线程上收集覆    
103          */                                       
104         if (ioctl(fd, KCOV_DISABLE, 0))           
105                 perror("ioctl"), exit(1);         
106         /* 释放资源 */                        
107         if (munmap(cover, COVER_SIZE * sizeof(    
108                 perror("munmap"), exit(1);        
109         if (close(fd))                            
110                 perror("close"), exit(1);         
111         return 0;                                 
112     }                                             
113                                                   
114 在使用 ``addr2line`` 传输后,程序输    
115                                                   
116     SyS_read                                      
117     fs/read_write.c:562                           
118     __fdget_pos                                   
119     fs/file.c:774                                 
120     __fget_light                                  
121     fs/file.c:746                                 
122     __fget_light                                  
123     fs/file.c:750                                 
124     __fget_light                                  
125     fs/file.c:760                                 
126     __fdget_pos                                   
127     fs/file.c:784                                 
128     SyS_read                                      
129     fs/read_write.c:562                           
130                                                   
131 如果一个程序需要从多个线程收集    
132 ``/sys/kernel/debug/kcov``。                     
133                                                   
134 接口的细粒度允许高效的创建测试    
135 ``/sys/kernel/debug/kcov``,启用了追踪    
136 环中创建了子进程。这个子进程只    
137 用覆盖率收集)。                          
138                                                   
139 操作数比较收集                             
140 --------------                                    
141                                                   
142 操作数比较收集和覆盖率收集类似    
143                                                   
144 .. code-block:: c                                 
145                                                   
146     /* 包含和上文一样的头文件和宏    
147                                                   
148     /* 每次记录的 64 位字的数量。 *    
149     #define KCOV_WORDS_PER_CMP 4                  
150                                                   
151     /*                                            
152      * 收集的比较种类的格式。          
153      *                                            
154      * 0 比特表示是否是一个编译时    
155      * 1 & 2 比特包含参数大小的 log2     
156      */                                           
157                                                   
158     #define KCOV_CMP_CONST          (1 << 0)      
159     #define KCOV_CMP_SIZE(n)        ((n) << 1)    
160     #define KCOV_CMP_MASK           KCOV_CMP_S    
161                                                   
162     int main(int argc, char **argv)               
163     {                                             
164         int fd;                                   
165         uint64_t *cover, type, arg1, arg2, is_    
166         unsigned long n, i;                       
167                                                   
168         fd = open("/sys/kernel/debug/kcov", O_    
169         if (fd == -1)                             
170                 perror("open"), exit(1);          
171         if (ioctl(fd, KCOV_INIT_TRACE, COVER_S    
172                 perror("ioctl"), exit(1);         
173         /*                                        
174         * 注意缓冲区指针的类型是 ui    
175         * 比较操作数都被提升为 uint6    
176         */                                        
177         cover = (uint64_t *)mmap(NULL, COVER_S    
178                                      PROT_READ    
179         if ((void*)cover == MAP_FAILED)           
180                 perror("mmap"), exit(1);          
181         /* 注意这里是 KCOV_TRACE_CMP 而    
182         if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_    
183                 perror("ioctl"), exit(1);         
184         __atomic_store_n(&cover[0], 0, __ATOMI    
185         read(-1, NULL, 0);                        
186         /* 读取收集到的比较操作数    
187         n = __atomic_load_n(&cover[0], __ATOMI    
188         for (i = 0; i < n; i++) {                 
189                 uint64_t ip;                      
190                                                   
191                 type = cover[i * KCOV_WORDS_PE    
192                 /* arg1 和 arg2 - 比较的    
193                 arg1 = cover[i * KCOV_WORDS_PE    
194                 arg2 = cover[i * KCOV_WORDS_PE    
195                 /* ip - 调用者的地址。     
196                 ip = cover[i * KCOV_WORDS_PER_    
197                 /* 操作数的大小。 */       
198                 size = 1 << ((type & KCOV_CMP_    
199                 /* is_const - 当操作数是    
200                 is_const = type & KCOV_CMP_CON    
201                 printf("ip: 0x%lx type: 0x%lx,    
202                         "size: %lu, %s\n",        
203                         ip, type, arg1, arg2,     
204                 is_const ? "const" : "non-cons    
205         }                                         
206         if (ioctl(fd, KCOV_DISABLE, 0))           
207                 perror("ioctl"), exit(1);         
208         /* 释放资源。 */                     
209         if (munmap(cover, COVER_SIZE * sizeof(    
210                 perror("munmap"), exit(1);        
211         if (close(fd))                            
212                 perror("close"), exit(1);         
213         return 0;                                 
214     }                                             
215                                                   
216 注意 KCOV 的模式(代码覆盖率收集    
217                                                   
218 远程覆盖率收集                             
219 --------------                                    
220                                                   
221 除了从用户空间进程发布的系统调    
222 他上下文中执行的内核中收集覆盖    
223                                                   
224 使用 KCOV 收集远程覆盖率要求:        
225                                                   
226 1. 修改内核源码并使用 ``kcov_remote_s    
227    覆盖率的代码片段。                    
228                                                   
229 2. 在用户空间的收集覆盖率的进程    
230                                                   
231 ``kcov_remote_start`` 和 ``kcov_remote_stop``    
232 ioctl 都接受可以识别特定覆盖率收    
233 行的上下文。                                
234                                                   
235 KCOV 支持在如下上下文中收集远程    
236                                                   
237 1. 全局内核后台任务。这些任务是    
238    USB HCD 产生一个 USB ``hub_event`` 工    
239                                                   
240 2. 局部内核后台任务。这些任务通    
241    生的,并且通常在进程退出时会    
242                                                   
243 3. 软中断。                                   
244                                                   
245 对于 #1 和 #3,必须选择一个独特的    
246 ``kcov_remote_start`` 调用。一个用户空    
247 ``kcov_remote_arg`` 结构体的 ``handle``     
248 ``KCOV_REMOTE_ENABLE``。这会将使用的 KC    
249 句柄标识的不同代码片段可以一次    
250                                                   
251 对于 #2,用户空间进程必须通过 ``k    
252 传递一个非零句柄。这个通用句柄    
253 ``kcov_handle`` 字段中并且需要通过自    
254 。这些任务需要在 ``kcov_remote_start``    
255 句柄。                                         
256                                                   
257 KCOV 对全局句柄和通用句柄均遵循    
258 。当前,只有最高位和低四位字节    
259                                                   
260 对于全局句柄,最高位的字节表示    
261 表示 USB 子系统类型。全局句柄的    
262 个 ``hub_event`` 工作器使用 USB 总线    
263                                                   
264 对于通用句柄,使用一个保留值 ``0    
265 的子系统。通用句柄的低 4 字节用    
266 该进程将通用句柄传递给 ``KCOV_REMOT    
267                                                   
268 实际上,如果只从系统中的单个用    
269 句柄的实例标识。然而,如果通用    
270 的实例标识。一个选择是使用进程    
271                                                   
272 下面的程序演示了如何使用 KCOV 从    
273 任务 #1 收集覆盖率:                      
274                                                   
275 .. code-block:: c                                 
276                                                   
277     /* 包含和上文一样的头文件和宏    
278                                                   
279     struct kcov_remote_arg {                      
280         __u32           trace_mode;               
281         __u32           area_size;                
282         __u32           num_handles;              
283         __aligned_u64   common_handle;            
284         __aligned_u64   handles[0];               
285     };                                            
286                                                   
287     #define KCOV_INIT_TRACE                       
288     #define KCOV_DISABLE                          
289     #define KCOV_REMOTE_ENABLE          _IOW('    
290                                                   
291     #define COVER_SIZE  (64 << 10)                
292                                                   
293     #define KCOV_TRACE_PC       0                 
294                                                   
295     #define KCOV_SUBSYSTEM_COMMON       (0x00u    
296     #define KCOV_SUBSYSTEM_USB  (0x01ull << 56    
297                                                   
298     #define KCOV_SUBSYSTEM_MASK (0xffull << 56    
299     #define KCOV_INSTANCE_MASK  (0xffffffffull    
300                                                   
301     static inline __u64 kcov_remote_handle(__u    
302     {                                             
303         if (subsys & ~KCOV_SUBSYSTEM_MASK || i    
304                 return 0;                         
305         return subsys | inst;                     
306     }                                             
307                                                   
308     #define KCOV_COMMON_ID      0x42              
309     #define KCOV_USB_BUS_NUM    1                 
310                                                   
311     int main(int argc, char **argv)               
312     {                                             
313         int fd;                                   
314         unsigned long *cover, n, i;               
315         struct kcov_remote_arg *arg;              
316                                                   
317         fd = open("/sys/kernel/debug/kcov", O_    
318         if (fd == -1)                             
319                 perror("open"), exit(1);          
320         if (ioctl(fd, KCOV_INIT_TRACE, COVER_S    
321                 perror("ioctl"), exit(1);         
322         cover = (unsigned long*)mmap(NULL, COV    
323                                      PROT_READ    
324         if ((void*)cover == MAP_FAILED)           
325                 perror("mmap"), exit(1);          
326                                                   
327         /* 通过通用句柄和 USB 总线 #1    
328         arg = calloc(1, sizeof(*arg) + sizeof(    
329         if (!arg)                                 
330                 perror("calloc"), exit(1);        
331         arg->trace_mode = KCOV_TRACE_PC;          
332         arg->area_size = COVER_SIZE;              
333         arg->num_handles = 1;                     
334         arg->common_handle = kcov_remote_handl    
335                                                   
336         arg->handles[0] = kcov_remote_handle(K    
337                                                   
338         if (ioctl(fd, KCOV_REMOTE_ENABLE, arg)    
339                 perror("ioctl"), free(arg), ex    
340         free(arg);                                
341                                                   
342         /*                                        
343          * 在这里用户需要触发执行    
344          * 该代码段要么使用通用句    
345          * 要么触发了一些 USB 总线 #1    
346          */                                       
347         sleep(2);                                 
348                                                   
349         n = __atomic_load_n(&cover[0], __ATOMI    
350         for (i = 0; i < n; i++)                   
351                 printf("0x%lx\n", cover[i + 1]    
352         if (ioctl(fd, KCOV_DISABLE, 0))           
353                 perror("ioctl"), exit(1);         
354         if (munmap(cover, COVER_SIZE * sizeof(    
355                 perror("munmap"), exit(1);        
356         if (close(fd))                            
357                 perror("close"), exit(1);         
358         return 0;                                 
359     }                                             
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php