aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-02-25 07:40:37 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-02-25 07:40:37 +0000
commitc3bb517174988117582d692ee52df37fe636fb3d (patch)
treee70ea06f2cc047626d0114a399c6830d35427390 /usr.sbin
parent89c1656950c1917eb3cb0c610360fa529d36dfef (diff)
parent362a42b214ff6f5ba0d376345a37d640d3017bfc (diff)
downloadsrc-c3bb517174988117582d692ee52df37fe636fb3d.tar.gz
src-c3bb517174988117582d692ee52df37fe636fb3d.zip
Notes
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pkg/pkg.c2
-rw-r--r--usr.sbin/pmcstat/Makefile3
-rw-r--r--usr.sbin/pmcstat/pmcpl_annotate_cg.c127
-rw-r--r--usr.sbin/pmcstat/pmcpl_annotate_cg.h42
-rw-r--r--usr.sbin/pmcstat/pmcstat.c12
-rw-r--r--usr.sbin/pmcstat/pmcstat.h1
-rw-r--r--usr.sbin/pmcstat/pmcstat_log.c6
7 files changed, 189 insertions, 4 deletions
diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c
index 6fae5713dae1..545d6dc0523b 100644
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -299,7 +299,7 @@ parse_fingerprint(ucl_object_t *obj)
fct = HASH_SHA256;
if (fct == HASH_UNKNOWN) {
- warnx("Unsupported hashing function: %s\n", function);
+ warnx("Unsupported hashing function: %s", function);
return (NULL);
}
diff --git a/usr.sbin/pmcstat/Makefile b/usr.sbin/pmcstat/Makefile
index c27e56d8d13b..b8c8081b6f61 100644
--- a/usr.sbin/pmcstat/Makefile
+++ b/usr.sbin/pmcstat/Makefile
@@ -9,6 +9,7 @@ DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSES}
LDADD= -lelf -lkvm -lpmc -lm -lncurses
SRCS= pmcstat.c pmcstat.h pmcstat_log.c \
-pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c pmcpl_calltree.c
+pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c \
+pmcpl_annotate_cg.c pmcpl_calltree.c
.include <bsd.prog.mk>
diff --git a/usr.sbin/pmcstat/pmcpl_annotate_cg.c b/usr.sbin/pmcstat/pmcpl_annotate_cg.c
new file mode 100644
index 000000000000..e90bda1ac522
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_annotate_cg.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * Copyright (c) 2014, Adrian Chadd, Netflix Inc.
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Transform a hwpmc(4) log into human readable form, and into
+ * gprof(1) compatible profiles.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/gmon.h>
+#include <sys/imgact_aout.h>
+#include <sys/imgact_elf.h>
+#include <sys/mman.h>
+#include <sys/pmc.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pmc.h>
+#include <pmclog.h>
+#include <sysexits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pmcstat.h"
+#include "pmcstat_log.h"
+#include "pmcpl_annotate_cg.h"
+
+/*
+ * Record a callchain.
+ */
+
+void
+pmcpl_annotate_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
+{
+ struct pmcstat_pcmap *map;
+ struct pmcstat_symbol *sym;
+ uintfptr_t newpc;
+ struct pmcstat_image *image;
+ int i;
+ char filename[PATH_MAX], funcname[PATH_MAX];
+ unsigned sline;
+
+ (void) pmcr; (void) nsamples; (void) usermode; (void) cpu;
+
+ for (i = 0; i < (int) nsamples; i++) {
+ map = NULL;
+ sym = NULL;
+ image = NULL;
+ filename[0] = '\0';
+ funcname[0] = '\0';
+ sline = 0;
+
+ map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[i]);
+ if (map != NULL) {
+ assert(cc[i] >= map->ppm_lowpc && cc[i] < map->ppm_highpc);
+ image = map->ppm_image;
+ newpc = cc[i] - (map->ppm_lowpc +
+ (image->pi_vaddr - image->pi_start));
+ sym = pmcstat_symbol_search(image, newpc);
+ }
+
+ if (map != NULL && image != NULL && sym != NULL) {
+ (void) pmcstat_image_addr2line(image, cc[i],
+ filename, sizeof(filename), &sline, funcname, sizeof(funcname));
+ }
+
+ if (map != NULL && sym != NULL) {
+ fprintf(args.pa_graphfile, "%p %s %s:%d\n",
+ (void *)cc[i],
+ funcname,
+ filename,
+ sline);
+ } else {
+ fprintf(args.pa_graphfile, "%p <unknown> ??:0\n",
+ (void *) cc[i]);
+ }
+ }
+ fprintf(args.pa_graphfile, "--\n");
+}
diff --git a/usr.sbin/pmcstat/pmcpl_annotate_cg.h b/usr.sbin/pmcstat/pmcpl_annotate_cg.h
new file mode 100644
index 000000000000..bd655f7c9e01
--- /dev/null
+++ b/usr.sbin/pmcstat/pmcpl_annotate_cg.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2005-2007, Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
+ * Copyright (c) 2014, Adrian Chadd, Netflix Inc.
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PMCSTAT_PL_ANNOTATE_CG_H_
+#define _PMCSTAT_PL_ANNOTATE_CG_H_
+
+/* Function prototypes */
+void pmcpl_annotate_cg_process(
+ struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
+ uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
+
+#endif /* _PMCSTAT_PL_ANNOTATE_CG_H_ */
diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
index cc43b820690d..3edba3f20db4 100644
--- a/usr.sbin/pmcstat/pmcstat.c
+++ b/usr.sbin/pmcstat/pmcstat.c
@@ -503,6 +503,7 @@ pmcstat_show_usage(void)
"\t -S spec\t allocate a system-wide sampling PMC\n"
"\t -T\t\t start in top mode\n"
"\t -W\t\t (toggle) show counts per context switch\n"
+ "\t -a <file>\t print sampled PCs and callgraph to \"file\"\n"
"\t -c cpu-list\t set cpus for subsequent system-wide PMCs\n"
"\t -d\t\t (toggle) track descendants\n"
"\t -f spec\t pass \"spec\" to as plugin option\n"
@@ -617,8 +618,14 @@ main(int argc, char **argv)
CPU_SET(hcpu, &cpumask);
while ((option = getopt(argc, argv,
- "CD:EF:G:M:NO:P:R:S:TWc:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1)
+ "CD:EF:G:M:NO:P:R:S:TWa:c:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1)
switch (option) {
+ case 'a': /* Annotate + callgraph */
+ args.pa_flags |= FLAG_DO_ANNOTATE;
+ args.pa_plugin = PMCSTAT_PL_ANNOTATE_CG;
+ graphfilename = optarg;
+ break;
+
case 'C': /* cumulative values */
use_cumulative_counts = !use_cumulative_counts;
args.pa_required |= FLAG_HAS_COUNTING_PMCS;
@@ -917,7 +924,8 @@ main(int argc, char **argv)
/* -m option is allowed with -R only. */
if (args.pa_flags & FLAG_DO_ANNOTATE && args.pa_inputpath == NULL)
- errx(EX_USAGE, "ERROR: option -m requires an input file");
+ errx(EX_USAGE, "ERROR: option %s requires an input file",
+ args.pa_plugin == PMCSTAT_PL_ANNOTATE ? "-m" : "-a");
/* -m option is not allowed combined with -g or -G. */
if (args.pa_flags & FLAG_DO_ANNOTATE &&
diff --git a/usr.sbin/pmcstat/pmcstat.h b/usr.sbin/pmcstat/pmcstat.h
index 6b64b76074fb..c8ec14de19c9 100644
--- a/usr.sbin/pmcstat/pmcstat.h
+++ b/usr.sbin/pmcstat/pmcstat.h
@@ -91,6 +91,7 @@
#define PMCSTAT_PL_GPROF 2
#define PMCSTAT_PL_ANNOTATE 3
#define PMCSTAT_PL_CALLTREE 4
+#define PMCSTAT_PL_ANNOTATE_CG 5
#define PMCSTAT_TOP_DELTA 0
#define PMCSTAT_TOP_ACCUM 1
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c
index fdcf9c403702..f0e493959acb 100644
--- a/usr.sbin/pmcstat/pmcstat_log.c
+++ b/usr.sbin/pmcstat/pmcstat_log.c
@@ -149,6 +149,7 @@ struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
#include "pmcpl_gprof.h"
#include "pmcpl_callgraph.h"
#include "pmcpl_annotate.h"
+#include "pmcpl_annotate_cg.h"
#include "pmcpl_calltree.h"
static struct pmc_plugins {
@@ -214,6 +215,11 @@ static struct pmc_plugins {
.pl_topdisplay = pmcpl_ct_topdisplay
},
{
+ .pl_name = "annotate_cg",
+ .pl_process = pmcpl_annotate_cg_process
+ },
+
+ {
.pl_name = NULL
}
};