summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2017-01-05 13:33:32 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-01-11 14:48:01 -0500
commit355637717d575f14169954c3ed31536d45778f08 (patch)
treee8a5b2d77fe882a2a50ab096900770bd0e7cd71a
parent7d132caaf9392853ad637c8e6e53333cbeb99aa5 (diff)
perf kallsyms: Introduce tool to look for extended symbol information on the running kernel
Its similar to doing grep on a /proc/kallsyms, but it also shows extra information like the path to the kernel module and the unrelocated addresses in it, to help in diagnosing problems. It is also helps demonstrate the use of the symbols routines so that tool writers can use them more effectively. Using it: $ perf kallsyms e1000_xmit_frame netif_rx usb_stor_set_xfer_buf e1000_xmit_frame: [e1000e] /lib/modules/4.9.0+/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko 0xffffffffc046fc10-0xffffffffc0470bb0 (0x19c80-0x1ac20) netif_rx: [kernel] [kernel.kallsyms] 0xffffffff916f03a0-0xffffffff916f0410 (0xffffffff916f03a0-0xffffffff916f0410) usb_stor_set_xfer_buf: [usb_storage] /lib/modules/4.9.0+/kernel/drivers/usb/storage/usb-storage.ko 0xffffffffc057aea0-0xffffffffc057af19 (0xf10-0xf89) $ Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-79bk9pakujn4l4vq0f90klv3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/Build1
-rw-r--r--tools/perf/Documentation/perf-kallsyms.txt24
-rw-r--r--tools/perf/builtin-help.c2
-rw-r--r--tools/perf/builtin-kallsyms.c67
-rw-r--r--tools/perf/builtin.h1
-rw-r--r--tools/perf/command-list.txt1
-rw-r--r--tools/perf/perf.c1
7 files changed, 96 insertions, 1 deletions
diff --git a/tools/perf/Build b/tools/perf/Build
index b12d5d1666e3..0b48806f93c2 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -7,6 +7,7 @@ perf-y += builtin-help.o
7perf-y += builtin-sched.o 7perf-y += builtin-sched.o
8perf-y += builtin-buildid-list.o 8perf-y += builtin-buildid-list.o
9perf-y += builtin-buildid-cache.o 9perf-y += builtin-buildid-cache.o
10perf-y += builtin-kallsyms.o
10perf-y += builtin-list.o 11perf-y += builtin-list.o
11perf-y += builtin-record.o 12perf-y += builtin-record.o
12perf-y += builtin-report.o 13perf-y += builtin-report.o
diff --git a/tools/perf/Documentation/perf-kallsyms.txt b/tools/perf/Documentation/perf-kallsyms.txt
new file mode 100644
index 000000000000..954ea9e21236
--- /dev/null
+++ b/tools/perf/Documentation/perf-kallsyms.txt
@@ -0,0 +1,24 @@
1perf-kallsyms(1)
2==============
3
4NAME
5----
6perf-kallsyms - Searches running kernel for symbols
7
8SYNOPSIS
9--------
10[verse]
11'perf kallsyms <options> symbol_name[,symbol_name...]'
12
13DESCRIPTION
14-----------
15This command searches the running kernel kallsyms file for the given symbol(s)
16and prints information about it, including the DSO, the kallsyms begin/end
17addresses and the addresses in the ELF kallsyms symbol table (for symbols in
18modules).
19
20OPTIONS
21-------
22-v::
23--verbose=::
24 Increase verbosity level, showing details about symbol table loading, etc.
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 3bdb2c78a21b..93da24a638be 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -434,7 +434,7 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
434 const char * const builtin_help_subcommands[] = { 434 const char * const builtin_help_subcommands[] = {
435 "buildid-cache", "buildid-list", "diff", "evlist", "help", "list", 435 "buildid-cache", "buildid-list", "diff", "evlist", "help", "list",
436 "record", "report", "bench", "stat", "timechart", "top", "annotate", 436 "record", "report", "bench", "stat", "timechart", "top", "annotate",
437 "script", "sched", "kmem", "lock", "kvm", "test", "inject", "mem", "data", 437 "script", "sched", "kallsyms", "kmem", "lock", "kvm", "test", "inject", "mem", "data",
438#ifdef HAVE_LIBELF_SUPPORT 438#ifdef HAVE_LIBELF_SUPPORT
439 "probe", 439 "probe",
440#endif 440#endif
diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c
new file mode 100644
index 000000000000..224bfc454b4a
--- /dev/null
+++ b/tools/perf/builtin-kallsyms.c
@@ -0,0 +1,67 @@
1/*
2 * builtin-kallsyms.c
3 *
4 * Builtin command: Look for a symbol in the running kernel and its modules
5 *
6 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
7 *
8 * Released under the GPL v2. (and only v2, not any later version)
9 */
10#include "builtin.h"
11#include <linux/compiler.h>
12#include <subcmd/parse-options.h>
13#include "debug.h"
14#include "machine.h"
15#include "symbol.h"
16
17static int __cmd_kallsyms(int argc, const char **argv)
18{
19 int i;
20 struct machine *machine = machine__new_kallsyms();
21
22 if (machine == NULL) {
23 pr_err("Couldn't read /proc/kallsyms\n");
24 return -1;
25 }
26
27 for (i = 0; i < argc; ++i) {
28 struct map *map;
29 struct symbol *symbol = machine__find_kernel_function_by_name(machine, argv[i], &map);
30
31 if (symbol == NULL) {
32 printf("%s: not found\n", argv[i]);
33 continue;
34 }
35
36 printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n",
37 symbol->name, map->dso->short_name, map->dso->long_name,
38 map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end),
39 symbol->start, symbol->end);
40 }
41
42 machine__delete(machine);
43 return 0;
44}
45
46int cmd_kallsyms(int argc, const char **argv, const char *prefix __maybe_unused)
47{
48 const struct option options[] = {
49 OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"),
50 OPT_END()
51 };
52 const char * const kallsyms_usage[] = {
53 "perf kallsyms [<options>] symbol_name",
54 NULL
55 };
56
57 argc = parse_options(argc, argv, options, kallsyms_usage, 0);
58 if (argc < 1)
59 usage_with_options(kallsyms_usage, options);
60
61 symbol_conf.sort_by_name = true;
62 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
63 if (symbol__init(NULL) < 0)
64 return -1;
65
66 return __cmd_kallsyms(argc, argv);
67}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 0bcf68e98ccc..b55f5be486a1 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -23,6 +23,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix);
23int cmd_evlist(int argc, const char **argv, const char *prefix); 23int cmd_evlist(int argc, const char **argv, const char *prefix);
24int cmd_help(int argc, const char **argv, const char *prefix); 24int cmd_help(int argc, const char **argv, const char *prefix);
25int cmd_sched(int argc, const char **argv, const char *prefix); 25int cmd_sched(int argc, const char **argv, const char *prefix);
26int cmd_kallsyms(int argc, const char **argv, const char *prefix);
26int cmd_list(int argc, const char **argv, const char *prefix); 27int cmd_list(int argc, const char **argv, const char *prefix);
27int cmd_record(int argc, const char **argv, const char *prefix); 28int cmd_record(int argc, const char **argv, const char *prefix);
28int cmd_report(int argc, const char **argv, const char *prefix); 29int cmd_report(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index ab5cbaa170d0..fb45613dba9e 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -12,6 +12,7 @@ perf-diff mainporcelain common
12perf-config mainporcelain common 12perf-config mainporcelain common
13perf-evlist mainporcelain common 13perf-evlist mainporcelain common
14perf-inject mainporcelain common 14perf-inject mainporcelain common
15perf-kallsyms mainporcelain common
15perf-kmem mainporcelain common 16perf-kmem mainporcelain common
16perf-kvm mainporcelain common 17perf-kvm mainporcelain common
17perf-list mainporcelain common 18perf-list mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index aa23b3347d6b..13c8a7db055e 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -47,6 +47,7 @@ static struct cmd_struct commands[] = {
47 { "diff", cmd_diff, 0 }, 47 { "diff", cmd_diff, 0 },
48 { "evlist", cmd_evlist, 0 }, 48 { "evlist", cmd_evlist, 0 },
49 { "help", cmd_help, 0 }, 49 { "help", cmd_help, 0 },
50 { "kallsyms", cmd_kallsyms, 0 },
50 { "list", cmd_list, 0 }, 51 { "list", cmd_list, 0 },
51 { "record", cmd_record, 0 }, 52 { "record", cmd_record, 0 },
52 { "report", cmd_report, 0 }, 53 { "report", cmd_report, 0 },