perf probe: Fix to probe an inline function which has no entry pc
[platform/kernel/linux-rpi.git] / tools / perf / util / probe-finder.c
index 505905f..7857ae7 100644 (file)
@@ -942,7 +942,7 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
                ret = find_probe_point_lazy(in_die, pf);
        else {
                /* Get probe address */
-               if (dwarf_entrypc(in_die, &addr) != 0) {
+               if (die_entrypc(in_die, &addr) != 0) {
                        pr_warning("Failed to get entry address of %s.\n",
                                   dwarf_diename(in_die));
                        return -ENOENT;
@@ -1245,6 +1245,17 @@ static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
        return n;
 }
 
+static bool trace_event_finder_overlap(struct trace_event_finder *tf)
+{
+       int i;
+
+       for (i = 0; i < tf->ntevs; i++) {
+               if (tf->pf.addr == tf->tevs[i].point.address)
+                       return true;
+       }
+       return false;
+}
+
 /* Add a found probe point into trace event list */
 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
@@ -1255,6 +1266,14 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
        struct perf_probe_arg *args = NULL;
        int ret, i;
 
+       /*
+        * For some reason (e.g. different column assigned to same address)
+        * This callback can be called with the address which already passed.
+        * Ignore it first.
+        */
+       if (trace_event_finder_overlap(tf))
+               return 0;
+
        /* Check number of tevs */
        if (tf->ntevs == tf->max_tevs) {
                pr_warning("Too many( > %d) probe point found.\n",
@@ -1559,7 +1578,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                /* Get function entry information */
                func = basefunc = dwarf_diename(&spdie);
                if (!func ||
-                   dwarf_entrypc(&spdie, &baseaddr) != 0 ||
+                   die_entrypc(&spdie, &baseaddr) != 0 ||
                    dwarf_decl_line(&spdie, &baseline) != 0) {
                        lineno = 0;
                        goto post;
@@ -1576,7 +1595,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
                                                &indie)) {
                        /* There is an inline function */
-                       if (dwarf_entrypc(&indie, &_addr) == 0 &&
+                       if (die_entrypc(&indie, &_addr) == 0 &&
                            _addr == addr) {
                                /*
                                 * addr is at an inline function entry.