summaryrefslogtreecommitdiff
path: root/tools/perf/util/symbol-elf.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2015-12-09 11:11:18 +0900
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-12-10 16:29:32 -0300
commite7a7865cc0da306542db0b9205cb0a467f59e33d (patch)
treee72b7bd3620c5d949fbd7f8efe8fb0a3b03e02bf /tools/perf/util/symbol-elf.c
parent9d8b172f29ac0e5d1923d348e395e9643625ef7f (diff)
perf symbols: Fix dso__load_sym to put dso
Fix dso__load_sym to put dso because dsos__add already got it. Refcnt debugger explain the problem: ---- ==== [0] ==== Unreclaimed dso: 0x19dd200 Refcount +1 => 1 at ./perf(dso__new+0x1ff) [0x4a62df] ./perf(dso__load_sym+0xe89) [0x503509] ./perf(dso__load_vmlinux+0xbf) [0x4aa77f] ./perf(dso__load_vmlinux_path+0x8c) [0x4aa8dc] ./perf() [0x50539a] ./perf(convert_perf_probe_events+0xd79) [0x50ad39] ./perf() [0x45600f] ./perf(cmd_probe+0x6c) [0x4566bc] ./perf() [0x47abc5] ./perf(main+0x610) [0x421f90] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f74dd0efaf5] ./perf() [0x4220a9] Refcount +1 => 2 at ./perf(dso__get+0x34) [0x4a65f4] ./perf(map__new2+0x76) [0x4be216] ./perf(dso__load_sym+0xee1) [0x503561] ./perf(dso__load_vmlinux+0xbf) [0x4aa77f] ./perf(dso__load_vmlinux_path+0x8c) [0x4aa8dc] ./perf() [0x50539a] ./perf(convert_perf_probe_events+0xd79) [0x50ad39] ./perf() [0x45600f] ./perf(cmd_probe+0x6c) [0x4566bc] ./perf() [0x47abc5] ./perf(main+0x610) [0x421f90] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f74dd0efaf5] ./perf() [0x4220a9] Refcount +1 => 3 at ./perf(dsos__add+0xf3) [0x4a6bc3] ./perf(dso__load_sym+0xfc1) [0x503641] ./perf(dso__load_vmlinux+0xbf) [0x4aa77f] ./perf(dso__load_vmlinux_path+0x8c) [0x4aa8dc] ./perf() [0x50539a] ./perf(convert_perf_probe_events+0xd79) [0x50ad39] ./perf() [0x45600f] ./perf(cmd_probe+0x6c) [0x4566bc] ./perf() [0x47abc5] ./perf(main+0x610) [0x421f90] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f74dd0efaf5] ./perf() [0x4220a9] Refcount -1 => 2 at ./perf(dso__put+0x2f) [0x4a664f] ./perf(map_groups__exit+0xb9) [0x4bee29] ./perf(machine__delete+0xb0) [0x4b93d0] ./perf(exit_probe_symbol_maps+0x28) [0x506718] ./perf() [0x45628a] ./perf(cmd_probe+0x6c) [0x4566bc] ./perf() [0x47abc5] ./perf(main+0x610) [0x421f90] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f74dd0efaf5] ./perf() [0x4220a9] Refcount -1 => 1 at ./perf(dso__put+0x2f) [0x4a664f] ./perf(machine__delete+0xfe) [0x4b941e] ./perf(exit_probe_symbol_maps+0x28) [0x506718] ./perf() [0x45628a] ./perf(cmd_probe+0x6c) [0x4566bc] ./perf() [0x47abc5] ./perf(main+0x610) [0x421f90] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f74dd0efaf5] ./perf() [0x4220a9] ---- So, in the dso__load_sym, dso is gotten 3 times, by dso__new, map__new2, and dsos__add. The last 2 is actually released by map_groups and machine__delete correspondingly. However, the first reference by dso__new, is never released. Committer note: Changed the place where the reference count is dropped to: Fix it by dropping it right after creating curr_map, since we know that either that operation failed and we need to drop the dso refcount or that it succeed and we have it referenced via curr_map->dso. Then only drop the curr_map refcount after we call dsos__add() to make sure we hold a reference to it via curr_map->dso. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/20151209021118.10245.49869.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/symbol-elf.c')
-rw-r--r--tools/perf/util/symbol-elf.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 53f19968bfa2..562b8ebeae5b 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1026,8 +1026,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
curr_dso->long_name_len = dso->long_name_len;
curr_map = map__new2(start, curr_dso,
map->type);
+ dso__put(curr_dso);
if (curr_map == NULL) {
- dso__put(curr_dso);
goto out_elf_end;
}
if (adjust_kernel_syms) {
@@ -1042,9 +1042,14 @@ int dso__load_sym(struct dso *dso, struct map *map,
}
curr_dso->symtab_type = dso->symtab_type;
map_groups__insert(kmaps, curr_map);
+ /*
+ * Add it before we drop the referece to curr_map,
+ * i.e. while we still are sure to have a reference
+ * to this DSO via curr_map->dso.
+ */
+ dsos__add(&map->groups->machine->dsos, curr_dso);
/* kmaps already got it */
map__put(curr_map);
- dsos__add(&map->groups->machine->dsos, curr_dso);
dso__set_loaded(curr_dso, map->type);
} else
curr_dso = curr_map->dso;