aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-probe.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-10-07 18:28:30 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-10-12 17:31:53 -0400
commit23e8ec0d1c410f2f1d81050ee155db229abb1707 (patch)
tree309462a3591f3239741373a413482abb03e49145 /tools/perf/builtin-probe.c
parent4ea42b181434bfc6a0a18d32214130a242d489bf (diff)
perf probe: Add perf probe command support without libdwarf
Enables 'perf probe' even if libdwarf is not installed. If libdwarf is not found, 'perf probe' just disables dwarf support. Users can use 'perf probe' to set up new events by using kprobe_events format. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Christoph Hellwig <hch@infradead.org> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Frank Ch. Eigler <fche@redhat.com> LKML-Reference: <20091007222830.1684.25665.stgit@dhcp-100-2-132.bos.redhat.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'tools/perf/builtin-probe.c')
-rw-r--r--tools/perf/builtin-probe.c42
1 files changed, 35 insertions, 7 deletions
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);