From 3db67897de73dd9dcccddc9084bd5e18e1e7dde2 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 20 Jan 2017 11:55:19 +0100 Subject: tools/kcovtrace: add KCOV-based tracing utility 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. --- tools/kcovtrace/kcovtrace.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 tools/kcovtrace/kcovtrace.c (limited to 'tools') diff --git a/tools/kcovtrace/kcovtrace.c b/tools/kcovtrace/kcovtrace.c new file mode 100644 index 000000000..2d6188c2c --- /dev/null +++ b/tools/kcovtrace/kcovtrace.c @@ -0,0 +1,62 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} -- cgit mrf-deployment