aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2011-06-27 03:27:45 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-07-15 16:19:08 -0400
commit190b57fcb9c5fed5414935a174094f534fc510bc (patch)
tree952c19ed78abe454715d357fd5d0f8c6af9efd55 /tools
parentff741783506c340035659a71be68ddb4068760d1 (diff)
perf probe: Add probed module in front of function
Add probed module name and ":" in front of function name if -m module option is given. In the result, the symbol name passed to kprobe-tracer becomes MODULE:FUNCTION, so that kallsyms can solve it as a symbol in the module correctly. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Link: http://lkml.kernel.org/r/20110627072745.6528.26416.stgit@fedora15 Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/probe-event.c47
-rw-r--r--tools/perf/util/probe-event.h1
2 files changed, 39 insertions, 9 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 920c1957d6d..ee3f41eec5c 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -226,14 +226,26 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
226 return 0; 226 return 0;
227} 227}
228 228
229static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
230 int ntevs, const char *module)
231{
232 int i;
233 for (i = 0; i < ntevs; i++) {
234 tevs[i].point.module = strdup(module);
235 if (!tevs[i].point.module)
236 return -ENOMEM;
237 }
238 return 0;
239}
240
229/* Try to find perf_probe_event with debuginfo */ 241/* Try to find perf_probe_event with debuginfo */
230static int try_to_find_probe_trace_events(struct perf_probe_event *pev, 242static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
231 struct probe_trace_event **tevs, 243 struct probe_trace_event **tevs,
232 int max_tevs, const char *module) 244 int max_tevs, const char *module)
233{ 245{
234 bool need_dwarf = perf_probe_event_need_dwarf(pev); 246 bool need_dwarf = perf_probe_event_need_dwarf(pev);
235 struct debuginfo *dinfo = open_debuginfo(module); 247 struct debuginfo *dinfo = open_debuginfo(module);
236 int ntevs; 248 int ntevs, ret = 0;
237 249
238 if (!dinfo) { 250 if (!dinfo) {
239 if (need_dwarf) { 251 if (need_dwarf) {
@@ -251,7 +263,10 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
251 263
252 if (ntevs > 0) { /* Succeeded to find trace events */ 264 if (ntevs > 0) { /* Succeeded to find trace events */
253 pr_debug("find %d probe_trace_events.\n", ntevs); 265 pr_debug("find %d probe_trace_events.\n", ntevs);
254 return ntevs; 266 if (module)
267 ret = add_module_to_probe_trace_events(*tevs, ntevs,
268 module);
269 return ret < 0 ? ret : ntevs;
255 } 270 }
256 271
257 if (ntevs == 0) { /* No error but failed to find probe point. */ 272 if (ntevs == 0) { /* No error but failed to find probe point. */
@@ -1010,7 +1025,7 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1010 1025
1011/* Parse probe_events event into struct probe_point */ 1026/* Parse probe_events event into struct probe_point */
1012static int parse_probe_trace_command(const char *cmd, 1027static int parse_probe_trace_command(const char *cmd,
1013 struct probe_trace_event *tev) 1028 struct probe_trace_event *tev)
1014{ 1029{
1015 struct probe_trace_point *tp = &tev->point; 1030 struct probe_trace_point *tp = &tev->point;
1016 char pr; 1031 char pr;
@@ -1043,8 +1058,14 @@ static int parse_probe_trace_command(const char *cmd,
1043 1058
1044 tp->retprobe = (pr == 'r'); 1059 tp->retprobe = (pr == 'r');
1045 1060
1046 /* Scan function name and offset */ 1061 /* Scan module name(if there), function name and offset */
1047 ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol, 1062 p = strchr(argv[1], ':');
1063 if (p) {
1064 tp->module = strndup(argv[1], p - argv[1]);
1065 p++;
1066 } else
1067 p = argv[1];
1068 ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol,
1048 &tp->offset); 1069 &tp->offset);
1049 if (ret == 1) 1070 if (ret == 1)
1050 tp->offset = 0; 1071 tp->offset = 0;
@@ -1289,9 +1310,10 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1289 if (buf == NULL) 1310 if (buf == NULL)
1290 return NULL; 1311 return NULL;
1291 1312
1292 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu", 1313 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
1293 tp->retprobe ? 'r' : 'p', 1314 tp->retprobe ? 'r' : 'p',
1294 tev->group, tev->event, 1315 tev->group, tev->event,
1316 tp->module ?: "", tp->module ? ":" : "",
1295 tp->symbol, tp->offset); 1317 tp->symbol, tp->offset);
1296 if (len <= 0) 1318 if (len <= 0)
1297 goto error; 1319 goto error;
@@ -1398,6 +1420,8 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
1398 free(tev->group); 1420 free(tev->group);
1399 if (tev->point.symbol) 1421 if (tev->point.symbol)
1400 free(tev->point.symbol); 1422 free(tev->point.symbol);
1423 if (tev->point.module)
1424 free(tev->point.module);
1401 for (i = 0; i < tev->nargs; i++) { 1425 for (i = 0; i < tev->nargs; i++) {
1402 if (tev->args[i].name) 1426 if (tev->args[i].name)
1403 free(tev->args[i].name); 1427 free(tev->args[i].name);
@@ -1749,7 +1773,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1749 /* Convert perf_probe_event with debuginfo */ 1773 /* Convert perf_probe_event with debuginfo */
1750 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module); 1774 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module);
1751 if (ret != 0) 1775 if (ret != 0)
1752 return ret; 1776 return ret; /* Found in debuginfo or got an error */
1753 1777
1754 /* Allocate trace event buffer */ 1778 /* Allocate trace event buffer */
1755 tev = *tevs = zalloc(sizeof(struct probe_trace_event)); 1779 tev = *tevs = zalloc(sizeof(struct probe_trace_event));
@@ -1762,6 +1786,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1762 ret = -ENOMEM; 1786 ret = -ENOMEM;
1763 goto error; 1787 goto error;
1764 } 1788 }
1789 tev->point.module = strdup(module);
1790 if (tev->point.module == NULL) {
1791 ret = -ENOMEM;
1792 goto error;
1793 }
1765 tev->point.offset = pev->point.offset; 1794 tev->point.offset = pev->point.offset;
1766 tev->point.retprobe = pev->point.retprobe; 1795 tev->point.retprobe = pev->point.retprobe;
1767 tev->nargs = pev->nargs; 1796 tev->nargs = pev->nargs;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 3434fc9d79d..a7dee835f49 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -10,6 +10,7 @@ extern bool probe_event_dry_run;
10/* kprobe-tracer tracing point */ 10/* kprobe-tracer tracing point */
11struct probe_trace_point { 11struct probe_trace_point {
12 char *symbol; /* Base symbol */ 12 char *symbol; /* Base symbol */
13 char *module; /* Module name */
13 unsigned long offset; /* Offset from symbol */ 14 unsigned long offset; /* Offset from symbol */
14 bool retprobe; /* Return probe flag */ 15 bool retprobe; /* Return probe flag */
15}; 16};