aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Makefile6
-rw-r--r--tools/perf/builtin-probe.c42
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/util/probe-finder.h2
4 files changed, 40 insertions, 12 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 6dabcf1a4df6..52b1f438e71a 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -385,6 +385,7 @@ BUILTIN_OBJS += builtin-stat.o
385BUILTIN_OBJS += builtin-timechart.o 385BUILTIN_OBJS += builtin-timechart.o
386BUILTIN_OBJS += builtin-top.o 386BUILTIN_OBJS += builtin-top.o
387BUILTIN_OBJS += builtin-trace.o 387BUILTIN_OBJS += builtin-trace.o
388BUILTIN_OBJS += builtin-probe.o
388 389
389PERFLIBS = $(LIB_FILE) 390PERFLIBS = $(LIB_FILE)
390 391
@@ -420,13 +421,12 @@ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf *
420endif 421endif
421 422
422ifneq ($(shell sh -c "(echo '\#include <libdwarf/dwarf.h>'; echo '\#include <libdwarf/libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y) 423ifneq ($(shell sh -c "(echo '\#include <libdwarf/dwarf.h>'; echo '\#include <libdwarf/libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
423 msg := $(warning No libdwarf.h found, disables probe subcommand. Please install libdwarf-dev/libdwarf-devel); 424 msg := $(warning No libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel);
425 BASIC_CFLAGS += -DNO_LIBDWARF
424else 426else
425 EXTLIBS += -lelf -ldwarf 427 EXTLIBS += -lelf -ldwarf
426 LIB_H += util/probe-finder.h 428 LIB_H += util/probe-finder.h
427 LIB_OBJS += util/probe-finder.o 429 LIB_OBJS += util/probe-finder.o
428 BUILTIN_OBJS += builtin-probe.o
429 BASIC_CFLAGS += -DSUPPORT_DWARF
430endif 430endif
431 431
432ifdef NO_DEMANGLE 432ifdef NO_DEMANGLE
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 24b64b5cefce..73c883b715cc 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -54,6 +54,7 @@ const char *default_search_path[NR_SEARCH_PATH] = {
54static struct { 54static struct {
55 char *vmlinux; 55 char *vmlinux;
56 char *release; 56 char *release;
57 int need_dwarf;
57 int nr_probe; 58 int nr_probe;
58 struct probe_point probes[MAX_PROBES]; 59 struct probe_point probes[MAX_PROBES];
59 char *events[MAX_PROBES]; 60 char *events[MAX_PROBES];
@@ -162,6 +163,8 @@ static int parse_probepoint(const struct option *opt __used,
162 pp->function, pp->file, pp->offset); 163 pp->function, pp->file, pp->offset);
163 } 164 }
164 free(argv[1]); 165 free(argv[1]);
166 if (pp->file)
167 session.need_dwarf = 1;
165 168
166 /* Copy arguments */ 169 /* Copy arguments */
167 pp->nr_args = argc - 2; 170 pp->nr_args = argc - 2;
@@ -173,15 +176,19 @@ static int parse_probepoint(const struct option *opt __used,
173 } 176 }
174 177
175 /* Ensure return probe has no C argument */ 178 /* Ensure return probe has no C argument */
176 if (retp) 179 for (i = 0; i < pp->nr_args; i++)
177 for (i = 0; i < pp->nr_args; i++) 180 if (is_c_varname(pp->args[i])) {
178 if (is_c_varname(pp->args[i])) 181 if (retp)
179 semantic_error("You can't specify local" 182 semantic_error("You can't specify local"
180 " variable for kretprobe"); 183 " variable for kretprobe");
184 session.need_dwarf = 1;
185 }
186
181 debug("%d arguments\n", pp->nr_args); 187 debug("%d arguments\n", pp->nr_args);
182 return 0; 188 return 0;
183} 189}
184 190
191#ifndef NO_LIBDWARF
185static int open_default_vmlinux(void) 192static int open_default_vmlinux(void)
186{ 193{
187 struct utsname uts; 194 struct utsname uts;
@@ -209,6 +216,7 @@ static int open_default_vmlinux(void)
209 } 216 }
210 return fd; 217 return fd;
211} 218}
219#endif
212 220
213static const char * const probe_usage[] = { 221static const char * const probe_usage[] = {
214 "perf probe [<options>] -P 'PROBEDEF' [-P 'PROBEDEF' ...]", 222 "perf probe [<options>] -P 'PROBEDEF' [-P 'PROBEDEF' ...]",
@@ -216,10 +224,16 @@ static const char * const probe_usage[] = {
216}; 224};
217 225
218static const struct option options[] = { 226static const struct option options[] = {
227#ifndef NO_LIBDWARF
219 OPT_STRING('k', "vmlinux", &session.vmlinux, "file", 228 OPT_STRING('k', "vmlinux", &session.vmlinux, "file",
220 "vmlinux/module pathname"), 229 "vmlinux/module pathname"),
230#endif
221 OPT_CALLBACK('P', "probe", NULL, 231 OPT_CALLBACK('P', "probe", NULL,
232#ifdef NO_LIBDWARF
233 "p|r:[GRP/]NAME FUNC[+OFFS] [ARG ...]",
234#else
222 "p|r:[GRP/]NAME FUNC[+OFFS][@SRC]|@SRC:LINE [ARG ...]", 235 "p|r:[GRP/]NAME FUNC[+OFFS][@SRC]|@SRC:LINE [ARG ...]",
236#endif
223 "probe point definition, where\n" 237 "probe point definition, where\n"
224 "\t\tp:\tkprobe probe\n" 238 "\t\tp:\tkprobe probe\n"
225 "\t\tr:\tkretprobe probe\n" 239 "\t\tr:\tkretprobe probe\n"
@@ -227,9 +241,13 @@ static const struct option options[] = {
227 "\t\tNAME:\tEvent name\n" 241 "\t\tNAME:\tEvent name\n"
228 "\t\tFUNC:\tFunction name\n" 242 "\t\tFUNC:\tFunction name\n"
229 "\t\tOFFS:\tOffset from function entry (in byte)\n" 243 "\t\tOFFS:\tOffset from function entry (in byte)\n"
244#ifdef NO_LIBDWARF
245 "\t\tARG:\tProbe argument (only \n"
246#else
230 "\t\tSRC:\tSource code path\n" 247 "\t\tSRC:\tSource code path\n"
231 "\t\tLINE:\tLine number\n" 248 "\t\tLINE:\tLine number\n"
232 "\t\tARG:\tProbe argument (local variable name or\n" 249 "\t\tARG:\tProbe argument (local variable name or\n"
250#endif
233 "\t\t\tkprobe-tracer argument format is supported.)\n", 251 "\t\t\tkprobe-tracer argument format is supported.)\n",
234 parse_probepoint), 252 parse_probepoint),
235 OPT_END() 253 OPT_END()
@@ -279,7 +297,7 @@ error:
279 297
280int cmd_probe(int argc, const char **argv, const char *prefix __used) 298int cmd_probe(int argc, const char **argv, const char *prefix __used)
281{ 299{
282 int i, j, fd, ret, need_dwarf = 0; 300 int i, j, fd, ret;
283 struct probe_point *pp; 301 struct probe_point *pp;
284 char buf[MAX_CMDLEN]; 302 char buf[MAX_CMDLEN];
285 303
@@ -288,12 +306,19 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
288 if (argc || session.nr_probe == 0) 306 if (argc || session.nr_probe == 0)
289 usage_with_options(probe_usage, options); 307 usage_with_options(probe_usage, options);
290 308
291 /* Synthesize return probes */ 309#ifdef NO_LIBDWARF
310 if (session.need_dwarf)
311 semantic_error("Dwarf-analysis is not supported");
312#endif
313
314 /* Synthesize probes without dwarf */
292 for (j = 0; j < session.nr_probe; j++) { 315 for (j = 0; j < session.nr_probe; j++) {
316#ifndef NO_LIBDWARF
293 if (session.events[j][0] != 'r') { 317 if (session.events[j][0] != 'r') {
294 need_dwarf = 1; 318 session.need_dwarf = 1;
295 continue; 319 continue;
296 } 320 }
321#endif
297 ret = synthesize_probepoint(&session.probes[j]); 322 ret = synthesize_probepoint(&session.probes[j]);
298 if (ret == -E2BIG) 323 if (ret == -E2BIG)
299 semantic_error("probe point is too long."); 324 semantic_error("probe point is too long.");
@@ -303,7 +328,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
303 } 328 }
304 } 329 }
305 330
306 if (!need_dwarf) 331#ifndef NO_LIBDWARF
332 if (!session.need_dwarf)
307 goto setup_probes; 333 goto setup_probes;
308 334
309 if (session.vmlinux) 335 if (session.vmlinux)
@@ -332,6 +358,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
332 close(fd); 358 close(fd);
333 359
334setup_probes: 360setup_probes:
361#endif /* !NO_LIBDWARF */
362
335 /* Settng up probe points */ 363 /* Settng up probe points */
336 snprintf(buf, MAX_CMDLEN, "%s/../kprobe_events", debugfs_path); 364 snprintf(buf, MAX_CMDLEN, "%s/../kprobe_events", debugfs_path);
337 fd = open(buf, O_WRONLY, O_APPEND); 365 fd = open(buf, O_WRONLY, O_APPEND);
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index f598120c0097..c570d177d5c6 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -295,9 +295,7 @@ static void handle_internal_command(int argc, const char **argv)
295 { "version", cmd_version, 0 }, 295 { "version", cmd_version, 0 },
296 { "trace", cmd_trace, 0 }, 296 { "trace", cmd_trace, 0 },
297 { "sched", cmd_sched, 0 }, 297 { "sched", cmd_sched, 0 },
298#ifdef SUPPORT_DWARF
299 { "probe", cmd_probe, 0 }, 298 { "probe", cmd_probe, 0 },
300#endif
301 }; 299 };
302 unsigned int i; 300 unsigned int i;
303 static const char ext[] = STRIP_EXTENSION; 301 static const char ext[] = STRIP_EXTENSION;
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index af920de64866..306810c32f6b 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -44,6 +44,7 @@ struct probe_point {
44 char *probes[MAX_PROBES]; /* Output buffers (will be allocated)*/ 44 char *probes[MAX_PROBES]; /* Output buffers (will be allocated)*/
45}; 45};
46 46
47#ifndef NO_LIBDWARF
47extern int find_probepoint(int fd, struct probe_point *pp); 48extern int find_probepoint(int fd, struct probe_point *pp);
48 49
49#include <libdwarf/dwarf.h> 50#include <libdwarf/dwarf.h>
@@ -64,5 +65,6 @@ struct probe_finder {
64 char *buf; /* Current output buffer */ 65 char *buf; /* Current output buffer */
65 int len; /* Length of output buffer */ 66 int len; /* Length of output buffer */
66}; 67};
68#endif /* NO_LIBDWARF */
67 69
68#endif /*_PROBE_FINDER_H */ 70#endif /*_PROBE_FINDER_H */