Skip to contentSkip to conversation

perf,tools: fix core dump caused by per-socket/core system-wide stat

PATCH In review [email protected] 4 participants 5 messages Oct 9, 2015 – Oct 22, 2015 perf events

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 perf,tools: fix core dump caused by per-socket/core system-wide stat

From: Kan Liang <[email protected]>

Perf will core dump if --per-socket/core -a are applied for perf stat.

The root cause is that cpu_map__build_map set refcnt of evlist's cpu_map to 1.
It should set refcnt for the newly created cpu_map, not evlist's cpu_map.

Here is the example:

perf stat -e cycles --per-socket -a sleep 1

Performance counter stats for 'system wide':

S0       36         30,196,257      cycles
S1       28         15,823,536      cycles
       1.001126828 seconds time elapsed

*** Error in `./perf': corrupted double-linked list: 0x00000000021f9090
***
======= Backtrace: =========
/lib64/libc.so.6[0x3002e7bbe7] /lib64/libc.so.6[0x3002e7d2b5] ./perf(perf_evsel__delete+0x28)[0x485bdd]
./perf[0x4800e8]
./perf(perf_evlist__delete+0x5e)[0x482cd5] ./perf(cmd_stat+0xf25)[0x432328]
./perf[0x4768e0]
./perf[0x476ad6]
./perf[0x476b41]
./perf(main+0x1d0)[0x476db2] /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45] ./perf[0x4202c5]

---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cpumap.c +1 -1
index c51c29f..dfc1f0b 100644
@@ -284,7 +284,7 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
-	atomic_set(&cpus->refcnt, 1);
+	atomic_set(&c->refcnt, 1);
 	*res = c;
 	return 0;
 }
Signature · 1 line
1.8.3.1
Acked-by on v1 1/1
#1 lore raw
Quoted 46 lines · On Fri, Oct 09, 2015 at 06:59:23AM -0400, [email protected] wrote:

From: Kan Liang <[email protected]>

Perf will core dump if --per-socket/core -a are applied for perf stat.

The root cause is that cpu_map__build_map set refcnt of evlist's cpu_map to 1.
It should set refcnt for the newly created cpu_map, not evlist's cpu_map.

Here is the example:

perf stat -e cycles --per-socket -a sleep 1

Performance counter stats for 'system wide':

S0       36         30,196,257      cycles
S1       28         15,823,536      cycles
       1.001126828 seconds time elapsed

*** Error in `./perf': corrupted double-linked list: 0x00000000021f9090
***
======= Backtrace: =========
/lib64/libc.so.6[0x3002e7bbe7] /lib64/libc.so.6[0x3002e7d2b5] ./perf(perf_evsel__delete+0x28)[0x485bdd]
./perf[0x4800e8]
./perf(perf_evlist__delete+0x5e)[0x482cd5] ./perf(cmd_stat+0xf25)[0x432328]
./perf[0x4768e0]
./perf[0x476ad6]
./perf[0x476b41]
./perf(main+0x1d0)[0x476db2] /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45] ./perf[0x4202c5]

---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cpumap.c +0 -0
index c51c29f..dfc1f0b 100644

tools/perf/util/cpumap.c static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, · line 287

Quoted 5 lines
tools/perf/util/cpumap.c +1 -1
@@ -284,7 +284,7 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
-	atomic_set(&cpus->refcnt, 1);
+	atomic_set(&c->refcnt, 1);

ouch ;-)

thanks,
jirka

author
#2 lore raw

Hi Arnaldo

Here is one more fix for perf/core need to be pulled.

Thanks,
Kan

Quoted 62 lines · On Fri, Oct 09, 2015 at 06:59:23AM -0400, [email protected] wrote:

tools/perf/util/cpumap.c static int cpu_map__build_map(struct cpu_map

Quoted 47 lines

From: Kan Liang <[email protected]>

Perf will core dump if --per-socket/core -a are applied for perf stat.

The root cause is that cpu_map__build_map set refcnt of evlist's cpu_map to 1.
It should set refcnt for the newly created cpu_map, not evlist's cpu_map.

Here is the example:

perf stat -e cycles --per-socket -a sleep 1

Performance counter stats for 'system wide':

S0       36         30,196,257      cycles
S1       28         15,823,536      cycles
       1.001126828 seconds time elapsed

*** Error in `./perf': corrupted double-linked list:
0x00000000021f9090
***
======= Backtrace: ========= /lib64/libc.so.6[0x3002e7bbe7] /lib64/libc.so.6[0x3002e7d2b5] ./perf(perf_evsel__delete+0x28)[0x485bdd] ./perf[0x4800e8] ./perf(perf_evlist__delete+0x5e)[0x482cd5] ./perf(cmd_stat+0xf25)[0x432328] ./perf[0x4768e0]
./perf[0x476ad6]
./perf[0x476b41]
./perf(main+0x1d0)[0x476db2] /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45] ./perf[0x4202c5]

---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cpumap.c index renamed from tools/perf/util/cpumap.c +0 -0

c51c29f..dfc1f0b 100644

tools/perf/util/cpumap.c +0 -0
@@ -284,7 +284,7 @@ static int cpu_map__build_map(struct cpu_map

*cpus, struct cpu_map **res,

tools/perf/util/cpumap.c static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, · line 287

Quoted 5 lines
tools/perf/util/cpumap.c +1 -1
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
-	atomic_set(&cpus->refcnt, 1);
+	atomic_set(&c->refcnt, 1);

ouch ;-)

thanks,
jirka

#3 lore raw

Em Mon, Oct 19, 2015 at 10:22:51PM +0000, Liang, Kan escreveu:

Quoted 3 lines

Hi Arnaldo

Here is one more fix for perf/core need to be pulled.

Thanks for the reminder, tried to reproduce on a two socket system, couldn't, but the fix is obvious enough, thanks, applied.

- Arnaldo

Quoted 65 lines

Thanks,
Kan

Quoted 62 lines · On Fri, Oct 09, 2015 at 06:59:23AM -0400, [email protected] wrote:

tools/perf/util/cpumap.c static int cpu_map__build_map(struct cpu_map

Quoted 47 lines

From: Kan Liang <[email protected]>

Perf will core dump if --per-socket/core -a are applied for perf stat.

The root cause is that cpu_map__build_map set refcnt of evlist's cpu_map to 1.
It should set refcnt for the newly created cpu_map, not evlist's cpu_map.

Here is the example:

perf stat -e cycles --per-socket -a sleep 1

Performance counter stats for 'system wide':

S0       36         30,196,257      cycles
S1       28         15,823,536      cycles
       1.001126828 seconds time elapsed

*** Error in `./perf': corrupted double-linked list:
0x00000000021f9090
***
======= Backtrace: ========= /lib64/libc.so.6[0x3002e7bbe7] /lib64/libc.so.6[0x3002e7d2b5] ./perf(perf_evsel__delete+0x28)[0x485bdd] ./perf[0x4800e8] ./perf(perf_evlist__delete+0x5e)[0x482cd5] ./perf(cmd_stat+0xf25)[0x432328] ./perf[0x4768e0]
./perf[0x476ad6]
./perf[0x476b41]
./perf(main+0x1d0)[0x476db2] /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45] ./perf[0x4202c5]

---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cpumap.c index renamed from tools/perf/util/cpumap.c +0 -0

c51c29f..dfc1f0b 100644

tools/perf/util/cpumap.c +0 -0
@@ -284,7 +284,7 @@ static int cpu_map__build_map(struct cpu_map

*cpus, struct cpu_map **res,

tools/perf/util/cpumap.c static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, · line 287

Quoted 5 lines
tools/perf/util/cpumap.c +1 -1
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
-	atomic_set(&cpus->refcnt, 1);
+	atomic_set(&c->refcnt, 1);

ouch ;-)

thanks,
jirka

#4 lore raw

[tip:perf/core] perf cpu_map: Fix core dump caused by per-socket/ core system-wide stat

In reply to [email protected]
perf cpu_map: Fix core dump caused by per-socket/core system-wide stat
Commit-ID:  bc1d03687b9be3a30aab8e8d78c7884449b6e511
Gitweb:     http://git.kernel.org/tip/bc1d03687b9be3a30aab8e8d78c7884449b6e511
Author:     Kan Liang <[email protected]>
AuthorDate: Fri, 9 Oct 2015 06:59:23 -0400
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Tue, 20 Oct 2015 15:54:20 -0300

perf cpu_map: Fix core dump caused by per-socket/core system-wide stat

Perf will core dump if --per-socket/core -a are applied for perf stat.

The root cause is that cpu_map__build_map set refcnt of evlist's cpu_map to 1. It should set refcnt for the newly created cpu_map, not evlist's cpu_map.

Here is the example:

  # perf stat -e cycles --per-socket -a sleep 1

Performance counter stats for 'system wide':

  S0       36         30,196,257      cycles
  S1       28         15,823,536      cycles
       1.001126828 seconds time elapsed

*** Error in `./perf': corrupted double-linked list: 0x00000000021f9090 *** ======= Backtrace: =========
/lib64/libc.so.6[0x3002e7bbe7]
/lib64/libc.so.6[0x3002e7d2b5] ./perf(perf_evsel__delete+0x28)[0x485bdd]
./perf[0x4800e8]
./perf(perf_evlist__delete+0x5e)[0x482cd5] ./perf(cmd_stat+0xf25)[0x432328]
./perf[0x4768e0]
./perf[0x476ad6]
./perf[0x476b41]
./perf(main+0x1d0)[0x476db2] /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45] ./perf[0x4202c5]

---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cpumap.c +1 -1
index b368453..aa6b490 100644
@@ -285,7 +285,7 @@ int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
-	atomic_set(&cpus->refcnt, 1);
+	atomic_set(&c->refcnt, 1);
 	*res = c;
 	return 0;
 }