Logo Search packages:      
Sourcecode: kcov version File versions  Download package

kprobe_coverage.c

/*
 * Copyright (C) 2010 Simon Kagstrom
 *
 * See COPYING for license details
 */
#define _GNU_SOURCE

#include <kc.h>
#include <stdio.h>
#include <utils.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>

static char debugfs_path[PATH_MAX];
static const char *kprobe_coverage_write_path;
static const char *kprobe_coverage_read_path;

/* From lttng */
static int lookup_debugfs(void)
{
      char mnt_dir[PATH_MAX];
      char mnt_type[PATH_MAX];
      int ret = -ENOENT;

      FILE *fp = fopen("/proc/mounts", "r");
      if (!fp)
            return -EINVAL;

      while (1) {
            if (fscanf(fp, "%*s %s %s %*s %*s %*s", mnt_dir, mnt_type) <= 0)
                  panic("Debugfs does not seem to be mounted anywhere\n");

            if (!strcmp(mnt_type, "debugfs")) {
                  strcpy(debugfs_path, mnt_dir);
                  break;
            }
      }

      kprobe_coverage_write_path = dir_concat(debugfs_path, "kprobe-coverage/control");
      kprobe_coverage_read_path = dir_concat(debugfs_path, "kprobe-coverage/control");
      panic_if (!file_exists(kprobe_coverage_write_path),
                  "kprobe-coverage/control not found in debugfs\n"
                  "please load the kprobe_coverage module.\n");

      fclose(fp);

      return ret;
}

static int setup_breakpoints(struct kc *kc)
{
      GHashTableIter iter;
      unsigned long key;
      struct kc_addr *val;
      FILE *fp = fopen(kprobe_coverage_write_path, "w");

      panic_if(!fp, "Can't open kprobe coverage file %s for writing\n",
                  kprobe_coverage_write_path);

      g_hash_table_iter_init(&iter, kc->addrs);
      while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&val))
            fprintf(fp, "%s%s0x%lx\n",
                        kc->module_name, strlen(kc->module_name) == 0 ? "" : ":",
                        val->addr);

      fclose(fp);

      return 0;
}


void kprobe_coverage_run(struct kc *kc, const char *write_path,
            const char *read_path)
{
      FILE *fp;

      /* First lookup the path */
      if (write_path && read_path) {
            kprobe_coverage_write_path = xstrdup(write_path);
            kprobe_coverage_read_path = xstrdup(read_path);
      } else
            lookup_debugfs();
      setup_breakpoints(kc);

      fp = fopen(kprobe_coverage_read_path, "r");
      panic_if (!fp, "Can't open %s for reading\n",
                  kprobe_coverage_write_path);

      while (!feof(fp)) {
            char *line = NULL;
            struct kc_addr *addr;
            unsigned long l_addr;
            char *endp;
            char *p;
            size_t sz = 0;

            if (getline(&line, &sz, fp) < 0)
                  break;
            p = line;
            if (strchr(p, ':'))
                  p = strchr(p, ':') + 1;
            l_addr = strtoul(p, &endp, 16);
            free(line);

            if (endp == p)
                  continue;
            addr = kc_lookup_addr(kc, l_addr);
            if (addr)
                  kc_addr_register_hit(addr);
      }
}

Generated by  Doxygen 1.6.0   Back to index