perf probe: Provide perf interface for uprobes

- Enhances perf to probe user space executables and libraries.
- Enhances -F/--funcs option of "perf probe" to list possible probe points in
  an executable file or library.
- Documents userspace probing support in perf.

[ Probing a function in the executable using function name  ]
perf probe -x /bin/zsh zfree

[ Probing a library function using function name ]
perf probe -x /lib64/libc.so.6 malloc

[ list probe-able functions in an executable ]
perf probe -F -x /bin/zsh

[ list probe-able functions in an library]
perf probe -F -x /lib/libc.so.6

Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Anton Arapov <anton@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Linux-mm <linux-mm@kvack.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20120416120909.30661.99781.sendpatchset@srdronam.in.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Srikar Dronamraju
2012-04-16 17:39:09 +05:30
committed by Arnaldo Carvalho de Melo
parent 5dcefda0fd
commit 225466f1c2
6 changed files with 409 additions and 104 deletions

View File

@@ -54,6 +54,7 @@ static struct {
bool show_ext_vars;
bool show_funcs;
bool mod_events;
bool uprobes;
int nevents;
struct perf_probe_event events[MAX_PROBES];
struct strlist *dellist;
@@ -75,6 +76,8 @@ static int parse_probe_event(const char *str)
return -1;
}
pev->uprobes = params.uprobes;
/* Parse a perf-probe command into event */
ret = parse_perf_probe_command(str, pev);
pr_debug("%d arguments\n", pev->nargs);
@@ -125,6 +128,28 @@ static int opt_del_probe_event(const struct option *opt __used,
return 0;
}
static int opt_set_target(const struct option *opt, const char *str,
int unset __used)
{
int ret = -ENOENT;
if (str && !params.target) {
if (!strcmp(opt->long_name, "exec"))
params.uprobes = true;
#ifdef DWARF_SUPPORT
else if (!strcmp(opt->long_name, "module"))
params.uprobes = false;
#endif
else
return ret;
params.target = str;
ret = 0;
}
return ret;
}
#ifdef DWARF_SUPPORT
static int opt_show_lines(const struct option *opt __used,
const char *str, int unset __used)
@@ -246,9 +271,9 @@ static const struct option options[] = {
"file", "vmlinux pathname"),
OPT_STRING('s', "source", &symbol_conf.source_prefix,
"directory", "path to kernel source"),
OPT_STRING('m', "module", &params.target,
"modname|path",
"target module name (for online) or path (for offline)"),
OPT_CALLBACK('m', "module", NULL, "modname|path",
"target module name (for online) or path (for offline)",
opt_set_target),
#endif
OPT__DRY_RUN(&probe_event_dry_run),
OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -260,6 +285,8 @@ static const struct option options[] = {
"\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
"\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
opt_set_filter),
OPT_CALLBACK('x', "exec", NULL, "executable|path",
"target executable name or path", opt_set_target),
OPT_END()
};
@@ -310,6 +337,10 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
pr_err(" Error: Don't use --list with --funcs.\n");
usage_with_options(probe_usage, options);
}
if (params.uprobes) {
pr_warning(" Error: Don't use --list with --exec.\n");
usage_with_options(probe_usage, options);
}
ret = show_perf_probe_events();
if (ret < 0)
pr_err(" Error: Failed to show event list. (%d)\n",
@@ -333,8 +364,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
if (!params.filter)
params.filter = strfilter__new(DEFAULT_FUNC_FILTER,
NULL);
ret = show_available_funcs(params.target,
params.filter);
ret = show_available_funcs(params.target, params.filter,
params.uprobes);
strfilter__delete(params.filter);
if (ret < 0)
pr_err(" Error: Failed to show functions."
@@ -343,7 +374,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
}
#ifdef DWARF_SUPPORT
if (params.show_lines) {
if (params.show_lines && !params.uprobes) {
if (params.mod_events) {
pr_err(" Error: Don't use --line with"
" --add/--del.\n");