mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] perf buildid-list: Fix segfault when show DSOs with hits
@ 2015-04-10  9:35 He Kuang
  2015-04-10 12:51 ` Arnaldo Carvalho de Melo
  2015-04-11  6:37 ` [tip:perf/core] " tip-bot for He Kuang
  0 siblings, 2 replies; 3+ messages in thread
From: He Kuang @ 2015-04-10  9:35 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, namhyung, jolsa; +Cc: wangnan0, linux-kernel

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>
---
 tools/perf/util/build-id.c | 8 ++------
 tools/perf/util/machine.c  | 4 +---
 tools/perf/util/machine.h  | 1 +
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index f7fb258..61867df 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,
 	dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
 		    event->fork.ppid, event->fork.ptid);
 
-	if (thread) {
-		rb_erase(&thread->rb_node, &machine->threads);
-		if (machine->last_match == thread)
-			thread__zput(machine->last_match);
-		thread__put(thread);
-	}
+	if (thread)
+		machine__remove_thread(machine, thread);
 
 	return 0;
 }
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e45c8f3..b7091c9 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -14,8 +14,6 @@
 #include "unwind.h"
 #include "linux/hash.h"
 
-static void machine__remove_thread(struct machine *machine, struct thread *th);
-
 static void dsos__init(struct dsos *dsos)
 {
 	INIT_LIST_HEAD(&dsos->head);
@@ -1253,7 +1251,7 @@ out_problem:
 	return 0;
 }
 
-static void machine__remove_thread(struct machine *machine, struct thread *th)
+void machine__remove_thread(struct machine *machine, struct thread *th)
 {
 	if (machine->last_match == th)
 		thread__zput(machine->last_match);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index e2faf3b..6d64ced 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);
 void machine__exit(struct machine *machine);
 void machine__delete_threads(struct machine *machine);
 void machine__delete(struct machine *machine);
+void machine__remove_thread(struct machine *machine, struct thread *th);
 
 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
 					   struct addr_location *al);
-- 
2.3.3.220.g9ab698f


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] perf buildid-list: Fix segfault when show DSOs with hits
  2015-04-10  9:35 [PATCH] perf buildid-list: Fix segfault when show DSOs with hits He Kuang
@ 2015-04-10 12:51 ` Arnaldo Carvalho de Melo
  2015-04-11  6:37 ` [tip:perf/core] " tip-bot for He Kuang
  1 sibling, 0 replies; 3+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-04-10 12:51 UTC (permalink / raw)
  To: He Kuang; +Cc: a.p.zijlstra, mingo, namhyung, jolsa, wangnan0, linux-kernel

Em Fri, Apr 10, 2015 at 05:35:00PM +0800, He Kuang escreveu:
> 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
>   ...

Thanks, applied.

- Arnaldo

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip:perf/core] perf buildid-list: Fix segfault when show DSOs with hits
  2015-04-10  9:35 [PATCH] perf buildid-list: Fix segfault when show DSOs with hits He Kuang
  2015-04-10 12:51 ` Arnaldo Carvalho de Melo
@ 2015-04-11  6:37 ` tip-bot for He Kuang
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for He Kuang @ 2015-04-11  6:37 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, wangnan0, hpa, namhyung, hekuang, mingo, tglx,
	a.p.zijlstra, jolsa, acme

Commit-ID:  5e78c69b72276853ac64070a010e6df64723dba9
Gitweb:     http://git.kernel.org/tip/5e78c69b72276853ac64070a010e6df64723dba9
Author:     He Kuang <hekuang@huawei.com>
AuthorDate: Fri, 10 Apr 2015 17:35:00 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 10 Apr 2015 10:13:59 -0300

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>
---
 tools/perf/util/build-id.c | 8 ++------
 tools/perf/util/machine.c  | 4 +---
 tools/perf/util/machine.h  | 1 +
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index f7fb258..61867df 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,
 	dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
 		    event->fork.ppid, event->fork.ptid);
 
-	if (thread) {
-		rb_erase(&thread->rb_node, &machine->threads);
-		if (machine->last_match == thread)
-			thread__zput(machine->last_match);
-		thread__put(thread);
-	}
+	if (thread)
+		machine__remove_thread(machine, thread);
 
 	return 0;
 }
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9c380a2..527e032 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -14,8 +14,6 @@
 #include "unwind.h"
 #include "linux/hash.h"
 
-static void machine__remove_thread(struct machine *machine, struct thread *th);
-
 static void dsos__init(struct dsos *dsos)
 {
 	INIT_LIST_HEAD(&dsos->head);
@@ -1256,7 +1254,7 @@ out_problem:
 	return 0;
 }
 
-static void machine__remove_thread(struct machine *machine, struct thread *th)
+void machine__remove_thread(struct machine *machine, struct thread *th)
 {
 	if (machine->last_match == th)
 		thread__zput(machine->last_match);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index e2faf3b..6d64ced 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);
 void machine__exit(struct machine *machine);
 void machine__delete_threads(struct machine *machine);
 void machine__delete(struct machine *machine);
+void machine__remove_thread(struct machine *machine, struct thread *th);
 
 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
 					   struct addr_location *al);

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-04-11  6:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-10  9:35 [PATCH] perf buildid-list: Fix segfault when show DSOs with hits He Kuang
2015-04-10 12:51 ` Arnaldo Carvalho de Melo
2015-04-11  6:37 ` [tip:perf/core] " tip-bot for He Kuang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome