From eb459da88574d295152cdff20e67486b08c3066d Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Thu, 14 Feb 2013 12:37:16 +0000 Subject: gcov: Add small utility to deal with test coverage information from Xen Currently the utility can read and reset coverage informations. Signed-off-by: Frediano Ziglio --- tools/misc/Makefile | 8 ++- tools/misc/xencov.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 tools/misc/xencov.c (limited to 'tools/misc') diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 22e60fd3d8..eef9411e1c 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -9,7 +9,7 @@ CFLAGS += $(CFLAGS_libxenstore) HDRS = $(wildcard *.h) -TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd +TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd xencov TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash xen-lowmemd TARGETS-$(CONFIG_MIGRATE) += xen-hptool TARGETS := $(TARGETS-y) @@ -22,7 +22,8 @@ INSTALL_BIN-y := xencons INSTALL_BIN-$(CONFIG_X86) += xen-detect INSTALL_BIN := $(INSTALL_BIN-y) -INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd xen-ringwatch +INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm xen-tmem-list-parse gtraceview \ + gtracestat xenlockprof xenwatchdogd xen-ringwatch xencov INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash xen-lowmemd INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool INSTALL_SBIN := $(INSTALL_SBIN-y) @@ -85,4 +86,7 @@ xen-lowmemd: xen-lowmemd.o gtraceview: gtraceview.o $(CC) $(LDFLAGS) -o $@ $< $(CURSES_LIBS) $(APPEND_LDFLAGS) +xencov: xencov.o + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) + -include $(DEPS) diff --git a/tools/misc/xencov.c b/tools/misc/xencov.c new file mode 100644 index 0000000000..6645a305a6 --- /dev/null +++ b/tools/misc/xencov.c @@ -0,0 +1,152 @@ +/* + * xencov: handle test coverage information from Xen. + * + * Copyright (c) 2013, Citrix Systems R&D Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static xc_interface *gcov_xch = NULL; + +static void gcov_init(void) +{ + gcov_xch = xc_interface_open(NULL, NULL, 0); + if ( !gcov_xch ) + err(1, "opening interface"); +} + +int gcov_get_info(int op, struct xen_sysctl *sys, void *ptr) +{ + struct xen_sysctl_coverage_op *cov; + + memset(sys, 0, sizeof(*sys)); + sys->cmd = XEN_SYSCTL_coverage_op; + + cov = &sys->u.coverage_op; + cov->cmd = op; + cov->u.raw_info.p = ptr; + + return xc_sysctl(gcov_xch, sys); +} + +static void gcov_read(const char *fn, int reset) +{ + struct xen_sysctl sys; + unsigned page_size = sysconf(_SC_PAGESIZE); + uint32_t total_len; + uint8_t *p; + size_t size; + FILE *f; + int op = reset ? XEN_SYSCTL_COVERAGE_read_and_reset : + XEN_SYSCTL_COVERAGE_read; + + /* get total length */ + if ( gcov_get_info(XEN_SYSCTL_COVERAGE_get_total_size, &sys, NULL) < 0 ) + err(1, "getting total length"); + total_len = sys.u.coverage_op.u.total_size; + fprintf(stderr, "returned %u bytes\n", (unsigned) total_len); + + /* safe check */ + if ( total_len > 16u * 1024u * 1024u ) + errx(1, "coverage size too big %u bytes\n", total_len); + + /* allocate */ + size = total_len + page_size; + size -= (size % page_size); + p = mmap(0, size, PROT_WRITE|PROT_READ, + MAP_PRIVATE|MAP_ANON|MAP_LOCKED, -1, 0); + if ( p == (uint8_t *) -1 ) + err(1, "mapping memory for coverage"); + + /* get data */ + memset(p, 0, total_len); + if ( gcov_get_info(op, &sys, p) < 0 ) + err(1, "getting coverage information"); + + /* write to a file */ + if ( strcmp(fn, "-") == 0 ) + f = stdout; + else + f = fopen(fn, "w"); + if ( !f ) + err(1, "opening output file"); + if ( fwrite(p, 1, total_len, f) != total_len ) + err(1, "writing coverage to file"); + if (f != stdout) + fclose(f); +} + +static void gcov_reset(void) +{ + struct xen_sysctl sys; + + if ( gcov_get_info(XEN_SYSCTL_COVERAGE_reset, &sys, NULL) < 0 ) + err(1, "resetting coverage information"); +} + +static void usage(int exit_code) +{ + FILE *out = exit_code ? stderr : stdout; + + fprintf(out, "xencov {reset|read|read-reset} []\n" + "\treset reset information\n" + "\tread read information from xen to filename\n" + "\tread-reset read and reset information from xen to filename\n" + "\tfilename optional filename (default output)\n" + ); + exit(exit_code); +} + +int main(int argc, char **argv) +{ + int opt; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + usage(0); + break; + default: + usage(1); + } + } + + argv += optind; + argc -= optind; + if (argc <= 0) + usage(1); + + gcov_init(); + + if ( strcmp(argv[0], "reset") == 0 ) + gcov_reset(); + else if ( strcmp(argv[0], "read") == 0 ) + gcov_read(argc > 1 ? argv[1] : "-", 0); + else if ( strcmp(argv[0], "read-reset") == 0 ) + gcov_read(argc > 1 ? argv[1] : "-", 1); + else + usage(1); + + return 0; +} + -- cgit v1.2.3