aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorHe Kuang <hekuang@huawei.com>2015-04-10 05:35:00 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-04-10 09:13:59 -0400
commit5e78c69b72276853ac64070a010e6df64723dba9 (patch)
tree5549ea875500fe48b774b14270ba00bef039f3ef /tools
parent1060ab857f64f33a9445881fd31fa91470aeb622 (diff)
perf buildid-list: Fix segfault when show DSOs with hits
commit: f3b623b8490a ("perf tools: Reference count struct thread") appends every thread->node to dead_threads in machine__remove_thread() and list_del_init() this node in thread__put(). perf_event__exit_del_thread() releases thread wihout using machine__remove_thread(), and causes a NULL pointer crash when list_del_init(&thread->node) is called. Fix this by using machine_remove_thread() instead of using thread__put() directly. This problem can be reproduced as following: $ perf record ls $ perf buildid-list --with-hits [ 3874.195070] perf[1018]: segfault at 0 ip 00000000004b0b15 sp 00007ffc35b44780 error 6 in perf[400000+166000] Segmentation fault After this patch: $ perf record ls $ perf buildid-list --with-hits bc23e7c3281e542650ba4324421d6acf78f4c23e /proc/kcore 643324cb0e969f30c56d660f167f84a150845511 [vdso] 0000000000000000000000000000000000000000 /bin/busybox ... Signed-off-by: He Kuang <hekuang@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/r/1428658500-6483-1-git-send-email-hekuang@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/build-id.c8
-rw-r--r--tools/perf/util/machine.c4
-rw-r--r--tools/perf/util/machine.h1
3 files changed, 4 insertions, 9 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index f7fb2587df69..61867dff5d5a 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -59,12 +59,8 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused,
59 dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, 59 dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
60 event->fork.ppid, event->fork.ptid); 60 event->fork.ppid, event->fork.ptid);
61 61
62 if (thread) { 62 if (thread)
63 rb_erase(&thread->rb_node, &machine->threads); 63 machine__remove_thread(machine, thread);
64 if (machine->last_match == thread)
65 thread__zput(machine->last_match);
66 thread__put(thread);
67 }
68 64
69 return 0; 65 return 0;
70} 66}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9c380a2caa54..527e032e24f6 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -14,8 +14,6 @@
14#include "unwind.h" 14#include "unwind.h"
15#include "linux/hash.h" 15#include "linux/hash.h"
16 16
17static void machine__remove_thread(struct machine *machine, struct thread *th);
18
19static void dsos__init(struct dsos *dsos) 17static void dsos__init(struct dsos *dsos)
20{ 18{
21 INIT_LIST_HEAD(&dsos->head); 19 INIT_LIST_HEAD(&dsos->head);
@@ -1256,7 +1254,7 @@ out_problem:
1256 return 0; 1254 return 0;
1257} 1255}
1258 1256
1259static void machine__remove_thread(struct machine *machine, struct thread *th) 1257void machine__remove_thread(struct machine *machine, struct thread *th)
1260{ 1258{
1261 if (machine->last_match == th) 1259 if (machine->last_match == th)
1262 thread__zput(machine->last_match); 1260 thread__zput(machine->last_match);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index e2faf3b47e7b..6d64cedb9d1e 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -120,6 +120,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
120void machine__exit(struct machine *machine); 120void machine__exit(struct machine *machine);
121void machine__delete_threads(struct machine *machine); 121void machine__delete_threads(struct machine *machine);
122void machine__delete(struct machine *machine); 122void machine__delete(struct machine *machine);
123void machine__remove_thread(struct machine *machine, struct thread *th);
123 124
124struct branch_info *sample__resolve_bstack(struct perf_sample *sample, 125struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
125 struct addr_location *al); 126 struct addr_location *al);