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:

committed by
Arnaldo Carvalho de Melo

parent
5dcefda0fd
commit
225466f1c2
@@ -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", ¶ms.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", ¶ms.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");
|
||||
|
Reference in New Issue
Block a user