diff options
| -rw-r--r-- | tools/perf/builtin-probe.c | 72 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/map.c | 14 |
3 files changed, 41 insertions, 47 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 8b4fdaeefa29..0584b7a0ed36 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
| @@ -38,33 +38,27 @@ | |||
| 38 | #include "util/strlist.h" | 38 | #include "util/strlist.h" |
| 39 | #include "util/event.h" | 39 | #include "util/event.h" |
| 40 | #include "util/debug.h" | 40 | #include "util/debug.h" |
| 41 | #include "util/symbol.h" | ||
| 42 | #include "util/thread.h" | ||
| 43 | #include "util/session.h" | ||
| 41 | #include "util/parse-options.h" | 44 | #include "util/parse-options.h" |
| 42 | #include "util/parse-events.h" /* For debugfs_path */ | 45 | #include "util/parse-events.h" /* For debugfs_path */ |
| 43 | #include "util/probe-finder.h" | 46 | #include "util/probe-finder.h" |
| 44 | #include "util/probe-event.h" | 47 | #include "util/probe-event.h" |
| 45 | 48 | ||
| 46 | /* Default vmlinux search paths */ | ||
| 47 | #define NR_SEARCH_PATH 4 | ||
| 48 | const char *default_search_path[NR_SEARCH_PATH] = { | ||
| 49 | "/lib/modules/%s/build/vmlinux", /* Custom build kernel */ | ||
| 50 | "/usr/lib/debug/lib/modules/%s/vmlinux", /* Red Hat debuginfo */ | ||
| 51 | "/boot/vmlinux-debug-%s", /* Ubuntu */ | ||
| 52 | "./vmlinux", /* CWD */ | ||
| 53 | }; | ||
| 54 | |||
| 55 | #define MAX_PATH_LEN 256 | 49 | #define MAX_PATH_LEN 256 |
| 56 | #define MAX_PROBES 128 | 50 | #define MAX_PROBES 128 |
| 57 | 51 | ||
| 58 | /* Session management structure */ | 52 | /* Session management structure */ |
| 59 | static struct { | 53 | static struct { |
| 60 | char *vmlinux; | ||
| 61 | char *release; | ||
| 62 | bool need_dwarf; | 54 | bool need_dwarf; |
| 63 | bool list_events; | 55 | bool list_events; |
| 64 | bool force_add; | 56 | bool force_add; |
| 65 | int nr_probe; | 57 | int nr_probe; |
| 66 | struct probe_point probes[MAX_PROBES]; | 58 | struct probe_point probes[MAX_PROBES]; |
| 67 | struct strlist *dellist; | 59 | struct strlist *dellist; |
| 60 | struct symbol_conf conf; | ||
| 61 | struct perf_session *psession; | ||
| 68 | } session; | 62 | } session; |
| 69 | 63 | ||
| 70 | 64 | ||
| @@ -122,33 +116,21 @@ static int opt_del_probe_event(const struct option *opt __used, | |||
| 122 | } | 116 | } |
| 123 | 117 | ||
| 124 | #ifndef NO_LIBDWARF | 118 | #ifndef NO_LIBDWARF |
| 125 | static int open_default_vmlinux(void) | 119 | static int open_vmlinux(void) |
| 126 | { | 120 | { |
| 127 | struct utsname uts; | 121 | struct map *kmap; |
| 128 | char fname[MAX_PATH_LEN]; | 122 | kmap = map_groups__find_by_name(&session.psession->kmaps, |
| 129 | int fd, ret, i; | 123 | MAP__FUNCTION, "[kernel.kallsyms]"); |
| 130 | 124 | if (!kmap) { | |
| 131 | ret = uname(&uts); | 125 | pr_debug("Could not find kernel map.\n"); |
| 132 | if (ret) { | 126 | return -ENOENT; |
| 133 | pr_debug("uname() failed.\n"); | ||
| 134 | return -errno; | ||
| 135 | } | 127 | } |
| 136 | session.release = uts.release; | 128 | if (map__load(kmap, session.psession, NULL) < 0) { |
| 137 | for (i = 0; i < NR_SEARCH_PATH; i++) { | 129 | pr_debug("Failed to load kernel map.\n"); |
| 138 | ret = snprintf(fname, MAX_PATH_LEN, | 130 | return -EINVAL; |
| 139 | default_search_path[i], session.release); | ||
| 140 | if (ret >= MAX_PATH_LEN || ret < 0) { | ||
| 141 | pr_debug("Filename(%d,%s) is too long.\n", i, | ||
| 142 | uts.release); | ||
| 143 | errno = E2BIG; | ||
| 144 | return -E2BIG; | ||
| 145 | } | ||
| 146 | pr_debug("try to open %s\n", fname); | ||
| 147 | fd = open(fname, O_RDONLY); | ||
| 148 | if (fd >= 0) | ||
| 149 | break; | ||
| 150 | } | 131 | } |
| 151 | return fd; | 132 | pr_debug("Try to open %s\n", kmap->dso->long_name); |
| 133 | return open(kmap->dso->long_name, O_RDONLY); | ||
| 152 | } | 134 | } |
| 153 | #endif | 135 | #endif |
| 154 | 136 | ||
| @@ -164,8 +146,8 @@ static const struct option options[] = { | |||
| 164 | OPT_BOOLEAN('v', "verbose", &verbose, | 146 | OPT_BOOLEAN('v', "verbose", &verbose, |
| 165 | "be more verbose (show parsed arguments, etc)"), | 147 | "be more verbose (show parsed arguments, etc)"), |
| 166 | #ifndef NO_LIBDWARF | 148 | #ifndef NO_LIBDWARF |
| 167 | OPT_STRING('k', "vmlinux", &session.vmlinux, "file", | 149 | OPT_STRING('k', "vmlinux", &session.conf.vmlinux_name, |
| 168 | "vmlinux/module pathname"), | 150 | "file", "vmlinux pathname"), |
| 169 | #endif | 151 | #endif |
| 170 | OPT_BOOLEAN('l', "list", &session.list_events, | 152 | OPT_BOOLEAN('l', "list", &session.list_events, |
| 171 | "list up current probe events"), | 153 | "list up current probe events"), |
| @@ -236,17 +218,23 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) | |||
| 236 | return 0; | 218 | return 0; |
| 237 | } | 219 | } |
| 238 | 220 | ||
| 221 | /* Initialize symbol maps for vmlinux */ | ||
| 222 | if (session.conf.vmlinux_name == NULL) | ||
| 223 | session.conf.try_vmlinux_path = true; | ||
| 224 | if (symbol__init(&session.conf) < 0) | ||
| 225 | die("Failed to init symbol map."); | ||
| 226 | session.psession = perf_session__new(NULL, O_WRONLY, false, | ||
| 227 | &session.conf); | ||
| 228 | if (session.psession == NULL) | ||
| 229 | die("Failed to init perf_session."); | ||
| 230 | |||
| 239 | if (session.need_dwarf) | 231 | if (session.need_dwarf) |
| 240 | #ifdef NO_LIBDWARF | 232 | #ifdef NO_LIBDWARF |
| 241 | die("Debuginfo-analysis is not supported"); | 233 | die("Debuginfo-analysis is not supported"); |
| 242 | #else /* !NO_LIBDWARF */ | 234 | #else /* !NO_LIBDWARF */ |
| 243 | pr_debug("Some probes require debuginfo.\n"); | 235 | pr_debug("Some probes require debuginfo.\n"); |
| 244 | 236 | ||
| 245 | if (session.vmlinux) { | 237 | fd = open_vmlinux(); |
| 246 | pr_debug("Try to open %s.", session.vmlinux); | ||
| 247 | fd = open(session.vmlinux, O_RDONLY); | ||
| 248 | } else | ||
| 249 | fd = open_default_vmlinux(); | ||
| 250 | if (fd < 0) { | 238 | if (fd < 0) { |
| 251 | if (session.need_dwarf) | 239 | if (session.need_dwarf) |
| 252 | die("Could not open debuginfo file."); | 240 | die("Could not open debuginfo file."); |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index a92e0b039a6a..8027309b0422 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -152,6 +152,8 @@ size_t map__fprintf(struct map *self, FILE *fp); | |||
| 152 | 152 | ||
| 153 | struct perf_session; | 153 | struct perf_session; |
| 154 | 154 | ||
| 155 | int map__load(struct map *self, struct perf_session *session, | ||
| 156 | symbol_filter_t filter); | ||
| 155 | struct symbol *map__find_symbol(struct map *self, struct perf_session *session, | 157 | struct symbol *map__find_symbol(struct map *self, struct perf_session *session, |
| 156 | u64 addr, symbol_filter_t filter); | 158 | u64 addr, symbol_filter_t filter); |
| 157 | struct symbol *map__find_symbol_by_name(struct map *self, const char *name, | 159 | struct symbol *map__find_symbol_by_name(struct map *self, const char *name, |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 8b3dd467adb5..c4d55a0da2ea 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
| @@ -104,12 +104,16 @@ void map__fixup_end(struct map *self) | |||
| 104 | 104 | ||
| 105 | #define DSO__DELETED "(deleted)" | 105 | #define DSO__DELETED "(deleted)" |
| 106 | 106 | ||
| 107 | static int map__load(struct map *self, struct perf_session *session, | 107 | int map__load(struct map *self, struct perf_session *session, |
| 108 | symbol_filter_t filter) | 108 | symbol_filter_t filter) |
| 109 | { | 109 | { |
| 110 | const char *name = self->dso->long_name; | 110 | const char *name = self->dso->long_name; |
| 111 | int nr = dso__load(self->dso, self, session, filter); | 111 | int nr; |
| 112 | 112 | ||
| 113 | if (dso__loaded(self->dso, self->type)) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | nr = dso__load(self->dso, self, session, filter); | ||
| 113 | if (nr < 0) { | 117 | if (nr < 0) { |
| 114 | if (self->dso->has_build_id) { | 118 | if (self->dso->has_build_id) { |
| 115 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | 119 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; |
| @@ -147,7 +151,7 @@ static int map__load(struct map *self, struct perf_session *session, | |||
| 147 | struct symbol *map__find_symbol(struct map *self, struct perf_session *session, | 151 | struct symbol *map__find_symbol(struct map *self, struct perf_session *session, |
| 148 | u64 addr, symbol_filter_t filter) | 152 | u64 addr, symbol_filter_t filter) |
| 149 | { | 153 | { |
| 150 | if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) | 154 | if (map__load(self, session, filter) < 0) |
| 151 | return NULL; | 155 | return NULL; |
| 152 | 156 | ||
| 153 | return dso__find_symbol(self->dso, self->type, addr); | 157 | return dso__find_symbol(self->dso, self->type, addr); |
| @@ -157,7 +161,7 @@ struct symbol *map__find_symbol_by_name(struct map *self, const char *name, | |||
| 157 | struct perf_session *session, | 161 | struct perf_session *session, |
| 158 | symbol_filter_t filter) | 162 | symbol_filter_t filter) |
| 159 | { | 163 | { |
| 160 | if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) | 164 | if (map__load(self, session, filter) < 0) |
| 161 | return NULL; | 165 | return NULL; |
| 162 | 166 | ||
| 163 | if (!dso__sorted_by_name(self->dso, self->type)) | 167 | if (!dso__sorted_by_name(self->dso, self->type)) |
