[PATCH -tip v3 10/11] perf-probe: Allow to add events on the local functions

2014-02-05 Thread Masami Hiramatsu
Allow to add events on the local functions without debuginfo.
(With the debuginfo, we can add events even on inlined functions)
Currently, probing on local functions requires debuginfo to
locate actual address. It is also possible without debuginfo since
we have symbol maps.

Without this change;
  
  # ./perf probe -a t_show
  Added new event:
probe:t_show (on t_show)

  You can now use it in all perf tools, such as:

  perf record -e probe:t_show -aR sleep 1

  # ./perf probe -x perf -a identity__map_ip
  no symbols found in /kbuild/ksrc/linux-3/tools/perf/perf, maybe install a 
debug package?
  Failed to load map.
Error: Failed to add events. (-22)
  
As the above results, perf probe just put one event
on the first found symbol for kprobe event. Moreover,
for uprobe event, perf probe failed to find local
functions.

With this change;
  
  # ./perf probe -a t_show
  Added new events:
probe:t_show (on t_show)
probe:t_show_1   (on t_show)
probe:t_show_2   (on t_show)
probe:t_show_3   (on t_show)

  You can now use it in all perf tools, such as:

  perf record -e probe:t_show_3 -aR sleep 1

  # ./perf probe -x perf -a identity__map_ip
  Added new events:
probe_perf:identity__map_ip (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)
probe_perf:identity__map_ip_1 (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)
probe_perf:identity__map_ip_2 (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)
probe_perf:identity__map_ip_3 (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)

  You can now use it in all perf tools, such as:

  perf record -e probe_perf:identity__map_ip_3 -aR sleep 1
  
Now we succeed to put events on every given local functions
for both kprobes and uprobes. :)

Note that this also introduces some symbol rbtree
iteration macros; symbols__for_each, dso__for_each_symbol,
and map__for_each_symbol. These are for walking through
the symbol list in a map.

Changes from v2:
  - Fix add_exec_to_probe_trace_events() not to convert address
to tp->symbol any more.
  - Fix to set kernel probes based on ref_reloc_sym.

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/dso.h |   10 +
 tools/perf/util/map.h |   10 +
 tools/perf/util/probe-event.c |  378 +++--
 tools/perf/util/symbol.h  |   11 +
 4 files changed, 204 insertions(+), 205 deletions(-)

diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index cd7d6f0..ab06f1c 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -102,6 +102,16 @@ struct dso {
char name[0];
 };
 
+/* dso__for_each_symbol - iterate over the symbols of given type
+ *
+ * @dso: the 'struct dso *' in which symbols itereated
+ * @pos: the 'struct symbol *' to use as a loop cursor
+ * @n: the 'struct rb_node *' to use as a temporary storage
+ * @type: the 'enum map_type' type of symbols
+ */
+#define dso__for_each_symbol(dso, pos, n, type)\
+   symbols__for_each_entry(&(dso)->symbols[(type)], pos, n)
+
 static inline void dso__set_loaded(struct dso *dso, enum map_type type)
 {
dso->loaded |= (1 << type);
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 257e513..f00f058 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -90,6 +90,16 @@ u64 map__objdump_2mem(struct map *map, u64 ip);
 
 struct symbol;
 
+/* map__for_each_symbol - iterate over the symbols in the given map
+ *
+ * @map: the 'struct map *' in which symbols itereated
+ * @pos: the 'struct symbol *' to use as a loop cursor
+ * @n: the 'struct rb_node *' to use as a temporary storage
+ * Note: caller must ensure map->dso is not NULL (map is loaded).
+ */
+#define map__for_each_symbol(map, pos, n)  \
+   dso__for_each_symbol(map->dso, pos, n, map->type)
+
 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
 
 void map__init(struct map *map, enum map_type type,
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3c35b7a..42bec67 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -70,8 +70,6 @@ static int e_snprintf(char *str, size_t size, const char 
*format, ...)
 }
 
 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
-static int convert_name_to_addr(struct perf_probe_event *pev,
-   const char *exec);
 static void clear_probe_trace_event(struct probe_trace_event *tev);
 static struct machine *host_machine;
 
@@ -249,6 +247,14 @@ out:
return ret;
 }
 
+static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
+{
+   int i;
+
+   for (i = 0; i < ntevs; i++)
+   clear_probe_trace_event(tevs + i);
+}
+
 #ifdef HAVE_DWARF_SUPPORT
 /* Open new debuginfo of given module */
 static struct debuginfo *open_debuginfo(const char *module)
@@ -353,8 +359,7 

[PATCH -tip v3 10/11] perf-probe: Allow to add events on the local functions

2014-02-05 Thread Masami Hiramatsu
Allow to add events on the local functions without debuginfo.
(With the debuginfo, we can add events even on inlined functions)
Currently, probing on local functions requires debuginfo to
locate actual address. It is also possible without debuginfo since
we have symbol maps.

Without this change;
  
  # ./perf probe -a t_show
  Added new event:
probe:t_show (on t_show)

  You can now use it in all perf tools, such as:

  perf record -e probe:t_show -aR sleep 1

  # ./perf probe -x perf -a identity__map_ip
  no symbols found in /kbuild/ksrc/linux-3/tools/perf/perf, maybe install a 
debug package?
  Failed to load map.
Error: Failed to add events. (-22)
  
As the above results, perf probe just put one event
on the first found symbol for kprobe event. Moreover,
for uprobe event, perf probe failed to find local
functions.

With this change;
  
  # ./perf probe -a t_show
  Added new events:
probe:t_show (on t_show)
probe:t_show_1   (on t_show)
probe:t_show_2   (on t_show)
probe:t_show_3   (on t_show)

  You can now use it in all perf tools, such as:

  perf record -e probe:t_show_3 -aR sleep 1

  # ./perf probe -x perf -a identity__map_ip
  Added new events:
probe_perf:identity__map_ip (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)
probe_perf:identity__map_ip_1 (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)
probe_perf:identity__map_ip_2 (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)
probe_perf:identity__map_ip_3 (on identity__map_ip in 
/kbuild/ksrc/linux-3/tools/perf/perf)

  You can now use it in all perf tools, such as:

  perf record -e probe_perf:identity__map_ip_3 -aR sleep 1
  
Now we succeed to put events on every given local functions
for both kprobes and uprobes. :)

Note that this also introduces some symbol rbtree
iteration macros; symbols__for_each, dso__for_each_symbol,
and map__for_each_symbol. These are for walking through
the symbol list in a map.

Changes from v2:
  - Fix add_exec_to_probe_trace_events() not to convert address
to tp-symbol any more.
  - Fix to set kernel probes based on ref_reloc_sym.

Signed-off-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
---
 tools/perf/util/dso.h |   10 +
 tools/perf/util/map.h |   10 +
 tools/perf/util/probe-event.c |  378 +++--
 tools/perf/util/symbol.h  |   11 +
 4 files changed, 204 insertions(+), 205 deletions(-)

diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index cd7d6f0..ab06f1c 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -102,6 +102,16 @@ struct dso {
char name[0];
 };
 
+/* dso__for_each_symbol - iterate over the symbols of given type
+ *
+ * @dso: the 'struct dso *' in which symbols itereated
+ * @pos: the 'struct symbol *' to use as a loop cursor
+ * @n: the 'struct rb_node *' to use as a temporary storage
+ * @type: the 'enum map_type' type of symbols
+ */
+#define dso__for_each_symbol(dso, pos, n, type)\
+   symbols__for_each_entry((dso)-symbols[(type)], pos, n)
+
 static inline void dso__set_loaded(struct dso *dso, enum map_type type)
 {
dso-loaded |= (1  type);
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 257e513..f00f058 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -90,6 +90,16 @@ u64 map__objdump_2mem(struct map *map, u64 ip);
 
 struct symbol;
 
+/* map__for_each_symbol - iterate over the symbols in the given map
+ *
+ * @map: the 'struct map *' in which symbols itereated
+ * @pos: the 'struct symbol *' to use as a loop cursor
+ * @n: the 'struct rb_node *' to use as a temporary storage
+ * Note: caller must ensure map-dso is not NULL (map is loaded).
+ */
+#define map__for_each_symbol(map, pos, n)  \
+   dso__for_each_symbol(map-dso, pos, n, map-type)
+
 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
 
 void map__init(struct map *map, enum map_type type,
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3c35b7a..42bec67 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -70,8 +70,6 @@ static int e_snprintf(char *str, size_t size, const char 
*format, ...)
 }
 
 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
-static int convert_name_to_addr(struct perf_probe_event *pev,
-   const char *exec);
 static void clear_probe_trace_event(struct probe_trace_event *tev);
 static struct machine *host_machine;
 
@@ -249,6 +247,14 @@ out:
return ret;
 }
 
+static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
+{
+   int i;
+
+   for (i = 0; i  ntevs; i++)
+   clear_probe_trace_event(tevs + i);
+}
+
 #ifdef HAVE_DWARF_SUPPORT
 /* Open new debuginfo of given module */
 static struct debuginfo *open_debuginfo(const char