Created
November 21, 2024 08:40
-
-
Save brant-ruan/7eab1774203d96a9cccb124bc3d4731e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc -o test_kcov test_kcov.c -static | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/ioctl.h> | |
#include <sys/mman.h> | |
#include <unistd.h> | |
// KCOV IOCTL 定义 | |
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long) | |
#define KCOV_ENABLE _IO('c', 100) | |
#define KCOV_DISABLE _IO('c', 101) | |
int main() { | |
const char *kcov_path = "/sys/kernel/debug/kcov"; | |
int kcov_fd; | |
unsigned long *kcov_buffer; | |
unsigned long kcov_size = 65536; // KCOV 缓冲区大小 | |
int fd; | |
// 打开 kcov 文件 | |
kcov_fd = open(kcov_path, O_RDWR); | |
if (kcov_fd < 0) { | |
perror("open kcov"); | |
return 1; | |
} | |
// 初始化 KCOV 缓冲区 | |
if (ioctl(kcov_fd, KCOV_INIT_TRACE, kcov_size) < 0) { | |
perror("ioctl KCOV_INIT_TRACE"); | |
close(kcov_fd); | |
return 1; | |
} | |
// 将 KCOV 缓冲区映射到用户空间 | |
kcov_buffer = mmap(NULL, kcov_size * sizeof(unsigned long), | |
PROT_READ | PROT_WRITE, MAP_SHARED, kcov_fd, 0); | |
if (kcov_buffer == MAP_FAILED) { | |
perror("mmap"); | |
close(kcov_fd); | |
return 1; | |
} | |
// 打开一个需要测试的文件或触发内核代码 | |
fd = open("/dev/null", O_RDWR); | |
if (fd < 0) { | |
perror("open /dev/null"); | |
munmap(kcov_buffer, kcov_size * sizeof(unsigned long)); | |
close(kcov_fd); | |
return 1; | |
} | |
// 启用 KCOV | |
if (ioctl(kcov_fd, KCOV_ENABLE, 0) < 0) { | |
perror("ioctl KCOV_ENABLE"); | |
close(fd); | |
munmap(kcov_buffer, kcov_size * sizeof(unsigned long)); | |
close(kcov_fd); | |
return 1; | |
} | |
// 模拟执行一些操作 | |
write(fd, "test", 4); | |
read(fd, NULL, 0); | |
// 禁用 KCOV | |
if (ioctl(kcov_fd, KCOV_DISABLE, 0) < 0) { | |
perror("ioctl KCOV_DISABLE"); | |
} | |
// 输出覆盖率数据 | |
unsigned long entries = kcov_buffer[0]; | |
printf("Coverage entries: %lu\n", entries); | |
for (unsigned long i = 1; i <= entries; i++) { | |
printf(" 0x%lx\n", kcov_buffer[i]); | |
} | |
// 清理资源 | |
close(fd); | |
munmap(kcov_buffer, kcov_size * sizeof(unsigned long)); | |
close(kcov_fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment