]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
perf probe: Skip overlapped location on searching variables
authorMasami Hiramatsu <mhiramat@kernel.org>
Wed, 30 Oct 2019 07:09:49 +0000 (16:09 +0900)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 29 Jan 2020 04:58:30 +0000 (23:58 -0500)
BugLink: https://bugs.launchpad.net/bugs/1860490
[ Upstream commit dee36a2abb67c175265d49b9a8c7dfa564463d9a ]

Since debuginfo__find_probes() callback function can be called with  the
location which already passed, the callback function must filter out
such overlapped locations.

add_probe_trace_event() has already done it by commit 1a375ae7659a
("perf probe: Skip same probe address for a given line"), but
add_available_vars() doesn't. Thus perf probe -v shows same address
repeatedly as below:

  # perf probe -V vfs_read:18
  Available variables at vfs_read:18
          @<vfs_read+217>
                  char*   buf
                  loff_t* pos
                  ssize_t ret
                  struct file*    file
          @<vfs_read+217>
                  char*   buf
                  loff_t* pos
                  ssize_t ret
                  struct file*    file
          @<vfs_read+226>
                  char*   buf
                  loff_t* pos
                  ssize_t ret
                  struct file*    file

With this fix, perf probe -V shows it correctly:

  # perf probe -V vfs_read:18
  Available variables at vfs_read:18
          @<vfs_read+217>
                  char*   buf
                  loff_t* pos
                  ssize_t ret
                  struct file*    file
          @<vfs_read+226>
                  char*   buf
                  loff_t* pos
                  ssize_t ret
                  struct file*    file

Fixes: cf6eb489e5c0 ("perf probe: Show accessible local variables")
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lore.kernel.org/lkml/157241938927.32002.4026859017790562751.stgit@devnote2
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
tools/perf/util/probe-finder.c

index f015a9fc805dbd91f0ad13b9fd72511aef55d9fd..763c06a3a47473653ae2d905d0aa114e10cb3891 100644 (file)
@@ -1405,6 +1405,18 @@ error:
        return DIE_FIND_CB_END;
 }
 
+static bool available_var_finder_overlap(struct available_var_finder *af)
+{
+       int i;
+
+       for (i = 0; i < af->nvls; i++) {
+               if (af->pf.addr == af->vls[i].point.address)
+                       return true;
+       }
+       return false;
+
+}
+
 /* Add a found vars into available variables list */
 static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
@@ -1415,6 +1427,14 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
        Dwarf_Die die_mem;
        int ret;
 
+       /*
+        * 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 (available_var_finder_overlap(af))
+               return 0;
+
        /* Check number of tevs */
        if (af->nvls == af->max_vls) {
                pr_warning("Too many( > %d) probe point found.\n", af->max_vls);