mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-24 11:59:58 +00:00
3db67897de
kcovtrace is like strace but show kernel coverage collected with KCOV. It is very simplistic at this point and does not support multithreaded processes, etc. It can be used to understand, for example, exact location where kernel bails out with an error for a particular syscall.
63 lines
1.9 KiB
C
63 lines
1.9 KiB
C
// Copyright 2017 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
// kcovtrace is like strace but show kernel coverage collected with KCOV.
|
|
// It is very simplistic at this point and does not support multithreaded processes, etc.
|
|
// It can be used to understand, for example, exact location where kernel bails out
|
|
// with an error for a particular syscall.
|
|
|
|
#include <fcntl.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
|
|
#define KCOV_ENABLE _IO('c', 100)
|
|
#define KCOV_DISABLE _IO('c', 101)
|
|
#define COVER_SIZE (16 << 20)
|
|
|
|
int main(int argc, char** argv, char** envp)
|
|
{
|
|
int fd, pid, status;
|
|
unsigned long *cover, n, i;
|
|
|
|
if (argc == 1)
|
|
fprintf(stderr, "usage: kcovtrace program [args...]\n"), exit(1);
|
|
fd = open("/sys/kernel/debug/kcov", O_RDWR);
|
|
if (fd == -1)
|
|
perror("open"), exit(1);
|
|
if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
|
|
perror("ioctl"), exit(1);
|
|
cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
|
|
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
if ((void*)cover == MAP_FAILED)
|
|
perror("mmap"), exit(1);
|
|
pid = fork();
|
|
if (pid < 0)
|
|
perror("fork"), exit(1);
|
|
if (pid == 0) {
|
|
if (ioctl(fd, KCOV_ENABLE, 0))
|
|
perror("ioctl"), exit(1);
|
|
__atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
|
|
execve(argv[1], argv + 1, envp);
|
|
perror("execve");
|
|
exit(1);
|
|
}
|
|
while (waitpid(-1, &status, __WALL) != pid) {
|
|
}
|
|
n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
|
|
for (i = 0; i < n; i++)
|
|
printf("0x%lx\n", cover[i + 1]);
|
|
if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
|
|
perror("munmap"), exit(1);
|
|
if (close(fd))
|
|
perror("close"), exit(1);
|
|
return 0;
|
|
}
|