summaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-05-10 16:23:34 -0400
committerIngo Molnar <mingo@kernel.org>2016-05-11 10:56:58 -0400
commit38f5d8b32f36bcac1f54d4511a81e02ed8771a29 (patch)
tree86df6a818bbbea9f2c585716ccf72e7332c872c4 /tools/perf
parentd2950158d0d7bc376503393ca5f73f6f8d27c56b (diff)
parent452e84012595d681f254a3a0d733fb0b18ffaf42 (diff)
Merge tag 'perf-core-for-mingo-20160510' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Recording 'dwarf' callchains do not need DWARF unwinding support (He Kuang) - Print recently added perf_event_attr.write_backward bit flag in -vv verbose mode (Arnaldo Carvalho de Melo) - Fix incorrect python db-export error message in 'perf script' (Chris Phlipot) - Fix handling of zero-length symbols (Chris Phlipot) - perf stat: Scale values by unit before metrics (Andi Kleen) Infrastructure changes: - Rewrite strbuf not to die(), making tools using it to check its return value instead (Masami Hiramatsu) - Support reading from backward ring buffer, add a 'perf test' entry for it (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-help.c18
-rw-r--r--tools/perf/perf.c8
-rw-r--r--tools/perf/tests/Build1
-rw-r--r--tools/perf/tests/backward-ring-buffer.c151
-rw-r--r--tools/perf/tests/builtin-test.c4
-rw-r--r--tools/perf/tests/tests.h1
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/cache.h19
-rw-r--r--tools/perf/util/dwarf-aux.c52
-rw-r--r--tools/perf/util/evlist.c50
-rw-r--r--tools/perf/util/evlist.h4
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/header.c31
-rw-r--r--tools/perf/util/help-unknown-cmd.c30
-rw-r--r--tools/perf/util/pmu.c10
-rw-r--r--tools/perf/util/probe-event.c143
-rw-r--r--tools/perf/util/probe-finder.c30
-rw-r--r--tools/perf/util/quote.c36
-rw-r--r--tools/perf/util/quote.h2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c2
-rw-r--r--tools/perf/util/stat.c4
-rw-r--r--tools/perf/util/strbuf.c93
-rw-r--r--tools/perf/util/strbuf.h25
-rw-r--r--tools/perf/util/symbol.c2
-rw-r--r--tools/perf/util/util.c2
-rw-r--r--tools/perf/util/util.h6
-rw-r--r--tools/perf/util/wrapper.c29
27 files changed, 510 insertions, 245 deletions
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index bc1de9b8fd67..f9830c902b78 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -61,6 +61,7 @@ static int check_emacsclient_version(void)
61 struct child_process ec_process; 61 struct child_process ec_process;
62 const char *argv_ec[] = { "emacsclient", "--version", NULL }; 62 const char *argv_ec[] = { "emacsclient", "--version", NULL };
63 int version; 63 int version;
64 int ret = -1;
64 65
65 /* emacsclient prints its version number on stderr */ 66 /* emacsclient prints its version number on stderr */
66 memset(&ec_process, 0, sizeof(ec_process)); 67 memset(&ec_process, 0, sizeof(ec_process));
@@ -71,7 +72,10 @@ static int check_emacsclient_version(void)
71 fprintf(stderr, "Failed to start emacsclient.\n"); 72 fprintf(stderr, "Failed to start emacsclient.\n");
72 return -1; 73 return -1;
73 } 74 }
74 strbuf_read(&buffer, ec_process.err, 20); 75 if (strbuf_read(&buffer, ec_process.err, 20) < 0) {
76 fprintf(stderr, "Failed to read emacsclient version\n");
77 goto out;
78 }
75 close(ec_process.err); 79 close(ec_process.err);
76 80
77 /* 81 /*
@@ -82,8 +86,7 @@ static int check_emacsclient_version(void)
82 86
83 if (prefixcmp(buffer.buf, "emacsclient")) { 87 if (prefixcmp(buffer.buf, "emacsclient")) {
84 fprintf(stderr, "Failed to parse emacsclient version.\n"); 88 fprintf(stderr, "Failed to parse emacsclient version.\n");
85 strbuf_release(&buffer); 89 goto out;
86 return -1;
87 } 90 }
88 91
89 version = atoi(buffer.buf + strlen("emacsclient")); 92 version = atoi(buffer.buf + strlen("emacsclient"));
@@ -92,12 +95,11 @@ static int check_emacsclient_version(void)
92 fprintf(stderr, 95 fprintf(stderr,
93 "emacsclient version '%d' too old (< 22).\n", 96 "emacsclient version '%d' too old (< 22).\n",
94 version); 97 version);
95 strbuf_release(&buffer); 98 } else
96 return -1; 99 ret = 0;
97 } 100out:
98
99 strbuf_release(&buffer); 101 strbuf_release(&buffer);
100 return 0; 102 return ret;
101} 103}
102 104
103static void exec_woman_emacs(const char *path, const char *page) 105static void exec_woman_emacs(const char *path, const char *page)
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 83ffe7cd7330..797000842d40 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -309,9 +309,11 @@ static int handle_alias(int *argcp, const char ***argv)
309 if (*argcp > 1) { 309 if (*argcp > 1) {
310 struct strbuf buf; 310 struct strbuf buf;
311 311
312 strbuf_init(&buf, PATH_MAX); 312 if (strbuf_init(&buf, PATH_MAX) < 0 ||
313 strbuf_addstr(&buf, alias_string); 313 strbuf_addstr(&buf, alias_string) < 0 ||
314 sq_quote_argv(&buf, (*argv) + 1, PATH_MAX); 314 sq_quote_argv(&buf, (*argv) + 1,
315 PATH_MAX) < 0)
316 die("Failed to allocate memory.");
315 free(alias_string); 317 free(alias_string);
316 alias_string = buf.buf; 318 alias_string = buf.buf;
317 } 319 }
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 449fe97a555f..66a28982547b 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -38,6 +38,7 @@ perf-y += cpumap.o
38perf-y += stat.o 38perf-y += stat.o
39perf-y += event_update.o 39perf-y += event_update.o
40perf-y += event-times.o 40perf-y += event-times.o
41perf-y += backward-ring-buffer.o
41 42
42$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 43$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
43 $(call rule_mkdir) 44 $(call rule_mkdir)
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c
new file mode 100644
index 000000000000..d9ba991a9a30
--- /dev/null
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -0,0 +1,151 @@
1/*
2 * Test backward bit in event attribute, read ring buffer from end to
3 * beginning
4 */
5
6#include <perf.h>
7#include <evlist.h>
8#include <sys/prctl.h>
9#include "tests.h"
10#include "debug.h"
11
12#define NR_ITERS 111
13
14static void testcase(void)
15{
16 int i;
17
18 for (i = 0; i < NR_ITERS; i++) {
19 char proc_name[10];
20
21 snprintf(proc_name, sizeof(proc_name), "p:%d\n", i);
22 prctl(PR_SET_NAME, proc_name);
23 }
24}
25
26static int count_samples(struct perf_evlist *evlist, int *sample_count,
27 int *comm_count)
28{
29 int i;
30
31 for (i = 0; i < evlist->nr_mmaps; i++) {
32 union perf_event *event;
33
34 perf_evlist__mmap_read_catchup(evlist, i);
35 while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) {
36 const u32 type = event->header.type;
37
38 switch (type) {
39 case PERF_RECORD_SAMPLE:
40 (*sample_count)++;
41 break;
42 case PERF_RECORD_COMM:
43 (*comm_count)++;
44 break;
45 default:
46 pr_err("Unexpected record of type %d\n", type);
47 return TEST_FAIL;
48 }
49 }
50 }
51 return TEST_OK;
52}
53
54static int do_test(struct perf_evlist *evlist, int mmap_pages,
55 int *sample_count, int *comm_count)
56{
57 int err;
58 char sbuf[STRERR_BUFSIZE];
59
60 err = perf_evlist__mmap(evlist, mmap_pages, true);
61 if (err < 0) {
62 pr_debug("perf_evlist__mmap: %s\n",
63 strerror_r(errno, sbuf, sizeof(sbuf)));
64 return TEST_FAIL;
65 }
66
67 perf_evlist__enable(evlist);
68 testcase();
69 perf_evlist__disable(evlist);
70
71 err = count_samples(evlist, sample_count, comm_count);
72 perf_evlist__munmap(evlist);
73 return err;
74}
75
76
77int test__backward_ring_buffer(int subtest __maybe_unused)
78{
79 int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0;
80 char pid[16], sbuf[STRERR_BUFSIZE];
81 struct perf_evlist *evlist;
82 struct perf_evsel *evsel __maybe_unused;
83 struct parse_events_error parse_error;
84 struct record_opts opts = {
85 .target = {
86 .uid = UINT_MAX,
87 .uses_mmap = true,
88 },
89 .freq = 0,
90 .mmap_pages = 256,
91 .default_interval = 1,
92 };
93
94 snprintf(pid, sizeof(pid), "%d", getpid());
95 pid[sizeof(pid) - 1] = '\0';
96 opts.target.tid = opts.target.pid = pid;
97
98 evlist = perf_evlist__new();
99 if (!evlist) {
100 pr_debug("No ehough memory to create evlist\n");
101 return TEST_FAIL;
102 }
103
104 err = perf_evlist__create_maps(evlist, &opts.target);
105 if (err < 0) {
106 pr_debug("Not enough memory to create thread/cpu maps\n");
107 goto out_delete_evlist;
108 }
109
110 bzero(&parse_error, sizeof(parse_error));
111 err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error);
112 if (err) {
113 pr_debug("Failed to parse tracepoint event, try use root\n");
114 ret = TEST_SKIP;
115 goto out_delete_evlist;
116 }
117
118 perf_evlist__config(evlist, &opts, NULL);
119
120 /* Set backward bit, ring buffer should be writing from end */
121 evlist__for_each(evlist, evsel)
122 evsel->attr.write_backward = 1;
123
124 err = perf_evlist__open(evlist);
125 if (err < 0) {
126 pr_debug("perf_evlist__open: %s\n",
127 strerror_r(errno, sbuf, sizeof(sbuf)));
128 goto out_delete_evlist;
129 }
130
131 ret = TEST_FAIL;
132 err = do_test(evlist, opts.mmap_pages, &sample_count,
133 &comm_count);
134 if (err != TEST_OK)
135 goto out_delete_evlist;
136
137 if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) {
138 pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n",
139 sample_count, comm_count);
140 goto out_delete_evlist;
141 }
142
143 err = do_test(evlist, 1, &sample_count, &comm_count);
144 if (err != TEST_OK)
145 goto out_delete_evlist;
146
147 ret = TEST_OK;
148out_delete_evlist:
149 perf_evlist__delete(evlist);
150 return ret;
151}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 93c467015e71..0e95c20ecf6e 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -208,6 +208,10 @@ static struct test generic_tests[] = {
208 .func = test__event_times, 208 .func = test__event_times,
209 }, 209 },
210 { 210 {
211 .desc = "Test backward reading from ring buffer",
212 .func = test__backward_ring_buffer,
213 },
214 {
211 .func = NULL, 215 .func = NULL,
212 }, 216 },
213}; 217};
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 0fc946989cf0..c57e72c826d2 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -86,6 +86,7 @@ int test__synthesize_stat(int subtest);
86int test__synthesize_stat_round(int subtest); 86int test__synthesize_stat_round(int subtest);
87int test__event_update(int subtest); 87int test__event_update(int subtest);
88int test__event_times(int subtest); 88int test__event_times(int subtest);
89int test__backward_ring_buffer(int subtest);
89 90
90#if defined(__arm__) || defined(__aarch64__) 91#if defined(__arm__) || defined(__aarch64__)
91#ifdef HAVE_DWARF_UNWIND_SUPPORT 92#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 027bb2b89d7f..8c6c8a0ca642 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -27,7 +27,6 @@ libperf-y += strlist.o
27libperf-y += strfilter.o 27libperf-y += strfilter.o
28libperf-y += top.o 28libperf-y += top.o
29libperf-y += usage.o 29libperf-y += usage.o
30libperf-y += wrapper.o
31libperf-y += dso.o 30libperf-y += dso.o
32libperf-y += symbol.o 31libperf-y += symbol.o
33libperf-y += symbol_fprintf.o 32libperf-y += symbol_fprintf.o
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 1f5a93c2c9a2..0d814bb74661 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -40,25 +40,6 @@ int split_cmdline(char *cmdline, const char ***argv);
40 40
41#define alloc_nr(x) (((x)+16)*3/2) 41#define alloc_nr(x) (((x)+16)*3/2)
42 42
43/*
44 * Realloc the buffer pointed at by variable 'x' so that it can hold
45 * at least 'nr' entries; the number of entries currently allocated
46 * is 'alloc', using the standard growing factor alloc_nr() macro.
47 *
48 * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
49 */
50#define ALLOC_GROW(x, nr, alloc) \
51 do { \
52 if ((nr) > alloc) { \
53 if (alloc_nr(alloc) < (nr)) \
54 alloc = (nr); \
55 else \
56 alloc = alloc_nr(alloc); \
57 x = xrealloc((x), alloc * sizeof(*(x))); \
58 } \
59 } while(0)
60
61
62static inline int is_absolute_path(const char *path) 43static inline int is_absolute_path(const char *path)
63{ 44{
64 return path[0] == '/'; 45 return path[0] == '/';
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index aea189b41cc8..a347b19c961a 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -915,8 +915,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
915 tmp = "*"; 915 tmp = "*";
916 else if (tag == DW_TAG_subroutine_type) { 916 else if (tag == DW_TAG_subroutine_type) {
917 /* Function pointer */ 917 /* Function pointer */
918 strbuf_add(buf, "(function_type)", 15); 918 return strbuf_add(buf, "(function_type)", 15);
919 return 0;
920 } else { 919 } else {
921 if (!dwarf_diename(&type)) 920 if (!dwarf_diename(&type))
922 return -ENOENT; 921 return -ENOENT;
@@ -927,14 +926,10 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
927 else if (tag == DW_TAG_enumeration_type) 926 else if (tag == DW_TAG_enumeration_type)
928 tmp = "enum "; 927 tmp = "enum ";
929 /* Write a base name */ 928 /* Write a base name */
930 strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type)); 929 return strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type));
931 return 0;
932 } 930 }
933 ret = die_get_typename(&type, buf); 931 ret = die_get_typename(&type, buf);
934 if (ret == 0) 932 return ret ? ret : strbuf_addstr(buf, tmp);
935 strbuf_addstr(buf, tmp);
936
937 return ret;
938} 933}
939 934
940/** 935/**
@@ -951,12 +946,10 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
951 ret = die_get_typename(vr_die, buf); 946 ret = die_get_typename(vr_die, buf);
952 if (ret < 0) { 947 if (ret < 0) {
953 pr_debug("Failed to get type, make it unknown.\n"); 948 pr_debug("Failed to get type, make it unknown.\n");
954 strbuf_add(buf, " (unknown_type)", 14); 949 ret = strbuf_add(buf, " (unknown_type)", 14);
955 } 950 }
956 951
957 strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); 952 return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
958
959 return 0;
960} 953}
961 954
962#ifdef HAVE_DWARF_GETLOCATIONS 955#ifdef HAVE_DWARF_GETLOCATIONS
@@ -999,22 +992,24 @@ static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
999 } 992 }
1000 993
1001 while ((offset = dwarf_ranges(&scopes[1], offset, &base, 994 while ((offset = dwarf_ranges(&scopes[1], offset, &base,
1002 &start, &end)) > 0) { 995 &start, &end)) > 0) {
1003 start -= entry; 996 start -= entry;
1004 end -= entry; 997 end -= entry;
1005 998
1006 if (first) { 999 if (first) {
1007 strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1000 ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1008 name, start, end); 1001 name, start, end);
1009 first = false; 1002 first = false;
1010 } else { 1003 } else {
1011 strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1004 ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1012 start, end); 1005 start, end);
1013 } 1006 }
1007 if (ret < 0)
1008 goto out;
1014 } 1009 }
1015 1010
1016 if (!first) 1011 if (!first)
1017 strbuf_add(buf, "]>", 2); 1012 ret = strbuf_add(buf, "]>", 2);
1018 1013
1019out: 1014out:
1020 free(scopes); 1015 free(scopes);
@@ -1054,31 +1049,32 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
1054 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) 1049 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
1055 return -EINVAL; 1050 return -EINVAL;
1056 1051
1057 while ((offset = dwarf_getlocations( 1052 while ((offset = dwarf_getlocations(&attr, offset, &base,
1058 &attr, offset, &base, 1053 &start, &end, &op, &nops)) > 0) {
1059 &start, &end, &op, &nops)) > 0) {
1060 if (start == 0) { 1054 if (start == 0) {
1061 /* Single Location Descriptions */ 1055 /* Single Location Descriptions */
1062 ret = die_get_var_innermost_scope(sp_die, vr_die, buf); 1056 ret = die_get_var_innermost_scope(sp_die, vr_die, buf);
1063 return ret; 1057 goto out;
1064 } 1058 }
1065 1059
1066 /* Location Lists */ 1060 /* Location Lists */
1067 start -= entry; 1061 start -= entry;
1068 end -= entry; 1062 end -= entry;
1069 if (first) { 1063 if (first) {
1070 strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1064 ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1071 name, start, end); 1065 name, start, end);
1072 first = false; 1066 first = false;
1073 } else { 1067 } else {
1074 strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1068 ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1075 start, end); 1069 start, end);
1076 } 1070 }
1071 if (ret < 0)
1072 goto out;
1077 } 1073 }
1078 1074
1079 if (!first) 1075 if (!first)
1080 strbuf_add(buf, "]>", 2); 1076 ret = strbuf_add(buf, "]>", 2);
1081 1077out:
1082 return ret; 1078 return ret;
1083} 1079}
1084#else 1080#else
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 17cd01421e7f..c4bfe11479a0 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -766,6 +766,56 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
766 return perf_mmap__read(md, evlist->overwrite, old, head, &md->prev); 766 return perf_mmap__read(md, evlist->overwrite, old, head, &md->prev);
767} 767}
768 768
769union perf_event *
770perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
771{
772 struct perf_mmap *md = &evlist->mmap[idx];
773 u64 head, end;
774 u64 start = md->prev;
775
776 /*
777 * Check if event was unmapped due to a POLLHUP/POLLERR.
778 */
779 if (!atomic_read(&md->refcnt))
780 return NULL;
781
782 head = perf_mmap__read_head(md);
783 if (!head)
784 return NULL;
785
786 /*
787 * 'head' pointer starts from 0. Kernel minus sizeof(record) form
788 * it each time when kernel writes to it, so in fact 'head' is
789 * negative. 'end' pointer is made manually by adding the size of
790 * the ring buffer to 'head' pointer, means the validate data can
791 * read is the whole ring buffer. If 'end' is positive, the ring
792 * buffer has not fully filled, so we must adjust 'end' to 0.
793 *
794 * However, since both 'head' and 'end' is unsigned, we can't
795 * simply compare 'end' against 0. Here we compare '-head' and
796 * the size of the ring buffer, where -head is the number of bytes
797 * kernel write to the ring buffer.
798 */
799 if (-head < (u64)(md->mask + 1))
800 end = 0;
801 else
802 end = head + md->mask + 1;
803
804 return perf_mmap__read(md, false, start, end, &md->prev);
805}
806
807void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
808{
809 struct perf_mmap *md = &evlist->mmap[idx];
810 u64 head;
811
812 if (!atomic_read(&md->refcnt))
813 return;
814
815 head = perf_mmap__read_head(md);
816 md->prev = head;
817}
818
769static bool perf_mmap__empty(struct perf_mmap *md) 819static bool perf_mmap__empty(struct perf_mmap *md)
770{ 820{
771 return perf_mmap__read_head(md) == md->prev && !md->auxtrace_mmap.base; 821 return perf_mmap__read_head(md) == md->prev && !md->auxtrace_mmap.base;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 208897a646ca..85d1b59802e8 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -129,6 +129,10 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
129 129
130union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx); 130union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
131 131
132union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist,
133 int idx);
134void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx);
135
132void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); 136void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
133 137
134int perf_evlist__open(struct perf_evlist *evlist); 138int perf_evlist__open(struct perf_evlist *evlist);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3371721a05f2..a23f54793e51 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1316,6 +1316,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
1316 PRINT_ATTRf(comm_exec, p_unsigned); 1316 PRINT_ATTRf(comm_exec, p_unsigned);
1317 PRINT_ATTRf(use_clockid, p_unsigned); 1317 PRINT_ATTRf(use_clockid, p_unsigned);
1318 PRINT_ATTRf(context_switch, p_unsigned); 1318 PRINT_ATTRf(context_switch, p_unsigned);
1319 PRINT_ATTRf(write_backward, p_unsigned);
1319 1320
1320 PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned); 1321 PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned);
1321 PRINT_ATTRf(bp_type, p_unsigned); 1322 PRINT_ATTRf(bp_type, p_unsigned);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 90680ec9f8b8..c6000d44f98c 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1819,7 +1819,8 @@ static int process_cpu_topology(struct perf_file_section *section,
1819 1819
1820 ph->env.nr_sibling_cores = nr; 1820 ph->env.nr_sibling_cores = nr;
1821 size += sizeof(u32); 1821 size += sizeof(u32);
1822 strbuf_init(&sb, 128); 1822 if (strbuf_init(&sb, 128) < 0)
1823 goto free_cpu;
1823 1824
1824 for (i = 0; i < nr; i++) { 1825 for (i = 0; i < nr; i++) {
1825 str = do_read_string(fd, ph); 1826 str = do_read_string(fd, ph);
@@ -1827,7 +1828,8 @@ static int process_cpu_topology(struct perf_file_section *section,
1827 goto error; 1828 goto error;
1828 1829
1829 /* include a NULL character at the end */ 1830 /* include a NULL character at the end */
1830 strbuf_add(&sb, str, strlen(str) + 1); 1831 if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
1832 goto error;
1831 size += string_size(str); 1833 size += string_size(str);
1832 free(str); 1834 free(str);
1833 } 1835 }
@@ -1849,7 +1851,8 @@ static int process_cpu_topology(struct perf_file_section *section,
1849 goto error; 1851 goto error;
1850 1852
1851 /* include a NULL character at the end */ 1853 /* include a NULL character at the end */
1852 strbuf_add(&sb, str, strlen(str) + 1); 1854 if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
1855 goto error;
1853 size += string_size(str); 1856 size += string_size(str);
1854 free(str); 1857 free(str);
1855 } 1858 }
@@ -1912,13 +1915,14 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
1912 /* nr nodes */ 1915 /* nr nodes */
1913 ret = readn(fd, &nr, sizeof(nr)); 1916 ret = readn(fd, &nr, sizeof(nr));
1914 if (ret != sizeof(nr)) 1917 if (ret != sizeof(nr))
1915 goto error; 1918 return -1;
1916 1919
1917 if (ph->needs_swap) 1920 if (ph->needs_swap)
1918 nr = bswap_32(nr); 1921 nr = bswap_32(nr);
1919 1922
1920 ph->env.nr_numa_nodes = nr; 1923 ph->env.nr_numa_nodes = nr;
1921 strbuf_init(&sb, 256); 1924 if (strbuf_init(&sb, 256) < 0)
1925 return -1;
1922 1926
1923 for (i = 0; i < nr; i++) { 1927 for (i = 0; i < nr; i++) {
1924 /* node number */ 1928 /* node number */
@@ -1940,15 +1944,17 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
1940 mem_free = bswap_64(mem_free); 1944 mem_free = bswap_64(mem_free);
1941 } 1945 }
1942 1946
1943 strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":", 1947 if (strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1944 node, mem_total, mem_free); 1948 node, mem_total, mem_free) < 0)
1949 goto error;
1945 1950
1946 str = do_read_string(fd, ph); 1951 str = do_read_string(fd, ph);
1947 if (!str) 1952 if (!str)
1948 goto error; 1953 goto error;
1949 1954
1950 /* include a NULL character at the end */ 1955 /* include a NULL character at the end */
1951 strbuf_add(&sb, str, strlen(str) + 1); 1956 if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
1957 goto error;
1952 free(str); 1958 free(str);
1953 } 1959 }
1954 ph->env.numa_nodes = strbuf_detach(&sb, NULL); 1960 ph->env.numa_nodes = strbuf_detach(&sb, NULL);
@@ -1982,7 +1988,8 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused
1982 } 1988 }
1983 1989
1984 ph->env.nr_pmu_mappings = pmu_num; 1990 ph->env.nr_pmu_mappings = pmu_num;
1985 strbuf_init(&sb, 128); 1991 if (strbuf_init(&sb, 128) < 0)
1992 return -1;
1986 1993
1987 while (pmu_num) { 1994 while (pmu_num) {
1988 if (readn(fd, &type, sizeof(type)) != sizeof(type)) 1995 if (readn(fd, &type, sizeof(type)) != sizeof(type))
@@ -1994,9 +2001,11 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused
1994 if (!name) 2001 if (!name)
1995 goto error; 2002 goto error;
1996 2003
1997 strbuf_addf(&sb, "%u:%s", type, name); 2004 if (strbuf_addf(&sb, "%u:%s", type, name) < 0)
2005 goto error;
1998 /* include a NULL character at the end */ 2006 /* include a NULL character at the end */
1999 strbuf_add(&sb, "", 1); 2007 if (strbuf_add(&sb, "", 1) < 0)
2008 goto error;
2000 2009
2001 if (!strcmp(name, "msr")) 2010 if (!strcmp(name, "msr"))
2002 ph->env.msr_pmu_type = type; 2011 ph->env.msr_pmu_type = type;
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c
index 43a98a4dc1e1..d62ccaeeadd6 100644
--- a/tools/perf/util/help-unknown-cmd.c
+++ b/tools/perf/util/help-unknown-cmd.c
@@ -27,16 +27,27 @@ static int levenshtein_compare(const void *p1, const void *p2)
27 return l1 != l2 ? l1 - l2 : strcmp(s1, s2); 27 return l1 != l2 ? l1 - l2 : strcmp(s1, s2);
28} 28}
29 29
30static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) 30static int add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
31{ 31{
32 unsigned int i; 32 unsigned int i, nr = cmds->cnt + old->cnt;
33 33 void *tmp;
34 ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); 34
35 35 if (nr > cmds->alloc) {
36 /* Choose bigger one to alloc */
37 if (alloc_nr(cmds->alloc) < nr)
38 cmds->alloc = nr;
39 else
40 cmds->alloc = alloc_nr(cmds->alloc);
41 tmp = realloc(cmds->names, cmds->alloc * sizeof(*cmds->names));
42 if (!tmp)
43 return -1;
44 cmds->names = tmp;
45 }
36 for (i = 0; i < old->cnt; i++) 46 for (i = 0; i < old->cnt; i++)
37 cmds->names[cmds->cnt++] = old->names[i]; 47 cmds->names[cmds->cnt++] = old->names[i];
38 zfree(&old->names); 48 zfree(&old->names);
39 old->cnt = 0; 49 old->cnt = 0;
50 return 0;
40} 51}
41 52
42const char *help_unknown_cmd(const char *cmd) 53const char *help_unknown_cmd(const char *cmd)
@@ -52,8 +63,11 @@ const char *help_unknown_cmd(const char *cmd)
52 63
53 load_command_list("perf-", &main_cmds, &other_cmds); 64 load_command_list("perf-", &main_cmds, &other_cmds);
54 65
55 add_cmd_list(&main_cmds, &aliases); 66 if (add_cmd_list(&main_cmds, &aliases) < 0 ||
56 add_cmd_list(&main_cmds, &other_cmds); 67 add_cmd_list(&main_cmds, &other_cmds) < 0) {
68 fprintf(stderr, "ERROR: Failed to allocate command list for unknown command.\n");
69 goto end;
70 }
57 qsort(main_cmds.names, main_cmds.cnt, 71 qsort(main_cmds.names, main_cmds.cnt,
58 sizeof(main_cmds.names), cmdname_compare); 72 sizeof(main_cmds.names), cmdname_compare);
59 uniq(&main_cmds); 73 uniq(&main_cmds);
@@ -99,6 +113,6 @@ const char *help_unknown_cmd(const char *cmd)
99 for (i = 0; i < n; i++) 113 for (i = 0; i < n; i++)
100 fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); 114 fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
101 } 115 }
102 116end:
103 exit(1); 117 exit(1);
104} 118}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index bf34468a99cb..ddb0261b2577 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -643,20 +643,20 @@ static int pmu_resolve_param_term(struct parse_events_term *term,
643static char *pmu_formats_string(struct list_head *formats) 643static char *pmu_formats_string(struct list_head *formats)
644{ 644{
645 struct perf_pmu_format *format; 645 struct perf_pmu_format *format;
646 char *str; 646 char *str = NULL;
647 struct strbuf buf; 647 struct strbuf buf = STRBUF_INIT;
648 unsigned i = 0; 648 unsigned i = 0;
649 649
650 if (!formats) 650 if (!formats)
651 return NULL; 651 return NULL;
652 652
653 strbuf_init(&buf, 0);
654 /* sysfs exported terms */ 653 /* sysfs exported terms */
655 list_for_each_entry(format, formats, list) 654 list_for_each_entry(format, formats, list)
656 strbuf_addf(&buf, i++ ? ",%s" : "%s", 655 if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
657 format->name); 656 goto error;
658 657
659 str = strbuf_detach(&buf, NULL); 658 str = strbuf_detach(&buf, NULL);
659error:
660 strbuf_release(&buf); 660 strbuf_release(&buf);
661 661
662 return str; 662 return str;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index c82c625395ab..74401a20106d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1677,28 +1677,37 @@ char *synthesize_perf_probe_arg(struct perf_probe_arg *pa)
1677{ 1677{
1678 struct perf_probe_arg_field *field = pa->field; 1678 struct perf_probe_arg_field *field = pa->field;
1679 struct strbuf buf; 1679 struct strbuf buf;
1680 char *ret; 1680 char *ret = NULL;
1681 int err;
1682
1683 if (strbuf_init(&buf, 64) < 0)
1684 return NULL;
1681 1685
1682 strbuf_init(&buf, 64);
1683 if (pa->name && pa->var) 1686 if (pa->name && pa->var)
1684 strbuf_addf(&buf, "%s=%s", pa->name, pa->var); 1687 err = strbuf_addf(&buf, "%s=%s", pa->name, pa->var);
1685 else 1688 else
1686 strbuf_addstr(&buf, pa->name ?: pa->var); 1689 err = strbuf_addstr(&buf, pa->name ?: pa->var);
1690 if (err)
1691 goto out;
1687 1692
1688 while (field) { 1693 while (field) {
1689 if (field->name[0] == '[') 1694 if (field->name[0] == '[')
1690 strbuf_addstr(&buf, field->name); 1695 err = strbuf_addstr(&buf, field->name);
1691 else 1696 else
1692 strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".", 1697 err = strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".",
1693 field->name); 1698 field->name);
1694 field = field->next; 1699 field = field->next;
1700 if (err)
1701 goto out;
1695 } 1702 }
1696 1703
1697 if (pa->type) 1704 if (pa->type)
1698 strbuf_addf(&buf, ":%s", pa->type); 1705 if (strbuf_addf(&buf, ":%s", pa->type) < 0)
1706 goto out;
1699 1707
1700 ret = strbuf_detach(&buf, NULL); 1708 ret = strbuf_detach(&buf, NULL);
1701 1709out:
1710 strbuf_release(&buf);
1702 return ret; 1711 return ret;
1703} 1712}
1704 1713
@@ -1706,18 +1715,23 @@ char *synthesize_perf_probe_arg(struct perf_probe_arg *pa)
1706static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 1715static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1707{ 1716{
1708 struct strbuf buf; 1717 struct strbuf buf;
1709 char *tmp; 1718 char *tmp, *ret = NULL;
1710 int len; 1719 int len, err = 0;
1720
1721 if (strbuf_init(&buf, 64) < 0)
1722 return NULL;
1711 1723
1712 strbuf_init(&buf, 64);
1713 if (pp->function) { 1724 if (pp->function) {
1714 strbuf_addstr(&buf, pp->function); 1725 if (strbuf_addstr(&buf, pp->function) < 0)
1726 goto out;
1715 if (pp->offset) 1727 if (pp->offset)
1716 strbuf_addf(&buf, "+%lu", pp->offset); 1728 err = strbuf_addf(&buf, "+%lu", pp->offset);
1717 else if (pp->line) 1729 else if (pp->line)
1718 strbuf_addf(&buf, ":%d", pp->line); 1730 err = strbuf_addf(&buf, ":%d", pp->line);
1719 else if (pp->retprobe) 1731 else if (pp->retprobe)
1720 strbuf_addstr(&buf, "%return"); 1732 err = strbuf_addstr(&buf, "%return");
1733 if (err)
1734 goto out;
1721 } 1735 }
1722 if (pp->file) { 1736 if (pp->file) {
1723 tmp = pp->file; 1737 tmp = pp->file;
@@ -1726,12 +1740,15 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1726 tmp = strchr(pp->file + len - 30, '/'); 1740 tmp = strchr(pp->file + len - 30, '/');
1727 tmp = tmp ? tmp + 1 : pp->file + len - 30; 1741 tmp = tmp ? tmp + 1 : pp->file + len - 30;
1728 } 1742 }
1729 strbuf_addf(&buf, "@%s", tmp); 1743 err = strbuf_addf(&buf, "@%s", tmp);
1730 if (!pp->function && pp->line) 1744 if (!err && !pp->function && pp->line)
1731 strbuf_addf(&buf, ":%d", pp->line); 1745 err = strbuf_addf(&buf, ":%d", pp->line);
1732 } 1746 }
1733 1747 if (!err)
1734 return strbuf_detach(&buf, NULL); 1748 ret = strbuf_detach(&buf, NULL);
1749out:
1750 strbuf_release(&buf);
1751 return ret;
1735} 1752}
1736 1753
1737#if 0 1754#if 0
@@ -1762,28 +1779,30 @@ char *synthesize_perf_probe_command(struct perf_probe_event *pev)
1762static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref, 1779static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1763 struct strbuf *buf, int depth) 1780 struct strbuf *buf, int depth)
1764{ 1781{
1782 int err;
1765 if (ref->next) { 1783 if (ref->next) {
1766 depth = __synthesize_probe_trace_arg_ref(ref->next, buf, 1784 depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
1767 depth + 1); 1785 depth + 1);
1768 if (depth < 0) 1786 if (depth < 0)
1769 goto out; 1787 return depth;
1770 } 1788 }
1771 strbuf_addf(buf, "%+ld(", ref->offset); 1789 err = strbuf_addf(buf, "%+ld(", ref->offset);
1772out: 1790 return (err < 0) ? err : depth;
1773 return depth;
1774} 1791}
1775 1792
1776static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, 1793static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1777 struct strbuf *buf) 1794 struct strbuf *buf)
1778{ 1795{
1779 struct probe_trace_arg_ref *ref = arg->ref; 1796 struct probe_trace_arg_ref *ref = arg->ref;
1780 int depth = 0; 1797 int depth = 0, err;
1781 1798
1782 /* Argument name or separator */ 1799 /* Argument name or separator */
1783 if (arg->name) 1800 if (arg->name)
1784 strbuf_addf(buf, " %s=", arg->name); 1801 err = strbuf_addf(buf, " %s=", arg->name);
1785 else 1802 else
1786 strbuf_addch(buf, ' '); 1803 err = strbuf_addch(buf, ' ');
1804 if (err)
1805 return err;
1787 1806
1788 /* Special case: @XXX */ 1807 /* Special case: @XXX */
1789 if (arg->value[0] == '@' && arg->ref) 1808 if (arg->value[0] == '@' && arg->ref)
@@ -1798,18 +1817,19 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1798 1817
1799 /* Print argument value */ 1818 /* Print argument value */
1800 if (arg->value[0] == '@' && arg->ref) 1819 if (arg->value[0] == '@' && arg->ref)
1801 strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset); 1820 err = strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset);
1802 else 1821 else
1803 strbuf_addstr(buf, arg->value); 1822 err = strbuf_addstr(buf, arg->value);
1804 1823
1805 /* Closing */ 1824 /* Closing */
1806 while (depth--) 1825 while (!err && depth--)
1807 strbuf_addch(buf, ')'); 1826 err = strbuf_addch(buf, ')');
1827
1808 /* Print argument type */ 1828 /* Print argument type */
1809 if (arg->type) 1829 if (!err && arg->type)
1810 strbuf_addf(buf, ":%s", arg->type); 1830 err = strbuf_addf(buf, ":%s", arg->type);
1811 1831
1812 return 0; 1832 return err;
1813} 1833}
1814 1834
1815char *synthesize_probe_trace_command(struct probe_trace_event *tev) 1835char *synthesize_probe_trace_command(struct probe_trace_event *tev)
@@ -1817,15 +1837,18 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1817 struct probe_trace_point *tp = &tev->point; 1837 struct probe_trace_point *tp = &tev->point;
1818 struct strbuf buf; 1838 struct strbuf buf;
1819 char *ret = NULL; 1839 char *ret = NULL;
1820 int i; 1840 int i, err;
1821 1841
1822 /* Uprobes must have tp->module */ 1842 /* Uprobes must have tp->module */
1823 if (tev->uprobes && !tp->module) 1843 if (tev->uprobes && !tp->module)
1824 return NULL; 1844 return NULL;
1825 1845
1826 strbuf_init(&buf, 32); 1846 if (strbuf_init(&buf, 32) < 0)
1827 strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p', 1847 return NULL;
1828 tev->group, tev->event); 1848
1849 if (strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p',
1850 tev->group, tev->event) < 0)
1851 goto error;
1829 /* 1852 /*
1830 * If tp->address == 0, then this point must be a 1853 * If tp->address == 0, then this point must be a
1831 * absolute address uprobe. 1854 * absolute address uprobe.
@@ -1839,14 +1862,16 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1839 1862
1840 /* Use the tp->address for uprobes */ 1863 /* Use the tp->address for uprobes */
1841 if (tev->uprobes) 1864 if (tev->uprobes)
1842 strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address); 1865 err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address);
1843 else if (!strncmp(tp->symbol, "0x", 2)) 1866 else if (!strncmp(tp->symbol, "0x", 2))
1844 /* Absolute address. See try_to_find_absolute_address() */ 1867 /* Absolute address. See try_to_find_absolute_address() */
1845 strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "", 1868 err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
1846 tp->module ? ":" : "", tp->address); 1869 tp->module ? ":" : "", tp->address);
1847 else 1870 else
1848 strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "", 1871 err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
1849 tp->module ? ":" : "", tp->symbol, tp->offset); 1872 tp->module ? ":" : "", tp->symbol, tp->offset);
1873 if (err)
1874 goto error;
1850 1875
1851 for (i = 0; i < tev->nargs; i++) 1876 for (i = 0; i < tev->nargs; i++)
1852 if (synthesize_probe_trace_arg(&tev->args[i], &buf) < 0) 1877 if (synthesize_probe_trace_arg(&tev->args[i], &buf) < 0)
@@ -1960,14 +1985,15 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev,
1960 if (tev->args[i].name) 1985 if (tev->args[i].name)
1961 pev->args[i].name = strdup(tev->args[i].name); 1986 pev->args[i].name = strdup(tev->args[i].name);
1962 else { 1987 else {
1963 strbuf_init(&buf, 32); 1988 if ((ret = strbuf_init(&buf, 32)) < 0)
1989 goto error;
1964 ret = synthesize_probe_trace_arg(&tev->args[i], &buf); 1990 ret = synthesize_probe_trace_arg(&tev->args[i], &buf);
1965 pev->args[i].name = strbuf_detach(&buf, NULL); 1991 pev->args[i].name = strbuf_detach(&buf, NULL);
1966 } 1992 }
1967 if (pev->args[i].name == NULL && ret >= 0) 1993 if (pev->args[i].name == NULL && ret >= 0)
1968 ret = -ENOMEM; 1994 ret = -ENOMEM;
1969 } 1995 }
1970 1996error:
1971 if (ret < 0) 1997 if (ret < 0)
1972 clear_perf_probe_event(pev); 1998 clear_perf_probe_event(pev);
1973 1999
@@ -2140,37 +2166,40 @@ static int perf_probe_event__sprintf(const char *group, const char *event,
2140 const char *module, 2166 const char *module,
2141 struct strbuf *result) 2167 struct strbuf *result)
2142{ 2168{
2143 int i; 2169 int i, ret;
2144 char *buf; 2170 char *buf;
2145 2171
2146 if (asprintf(&buf, "%s:%s", group, event) < 0) 2172 if (asprintf(&buf, "%s:%s", group, event) < 0)
2147 return -errno; 2173 return -errno;
2148 strbuf_addf(result, " %-20s (on ", buf); 2174 ret = strbuf_addf(result, " %-20s (on ", buf);
2149 free(buf); 2175 free(buf);
2176 if (ret)
2177 return ret;
2150 2178
2151 /* Synthesize only event probe point */ 2179 /* Synthesize only event probe point */
2152 buf = synthesize_perf_probe_point(&pev->point); 2180 buf = synthesize_perf_probe_point(&pev->point);
2153 if (!buf) 2181 if (!buf)
2154 return -ENOMEM; 2182 return -ENOMEM;
2155 strbuf_addstr(result, buf); 2183 ret = strbuf_addstr(result, buf);
2156 free(buf); 2184 free(buf);
2157 2185
2158 if (module) 2186 if (!ret && module)
2159 strbuf_addf(result, " in %s", module); 2187 ret = strbuf_addf(result, " in %s", module);
2160 2188
2161 if (pev->nargs > 0) { 2189 if (!ret && pev->nargs > 0) {
2162 strbuf_add(result, " with", 5); 2190 ret = strbuf_add(result, " with", 5);
2163 for (i = 0; i < pev->nargs; i++) { 2191 for (i = 0; !ret && i < pev->nargs; i++) {
2164 buf = synthesize_perf_probe_arg(&pev->args[i]); 2192 buf = synthesize_perf_probe_arg(&pev->args[i]);
2165 if (!buf) 2193 if (!buf)
2166 return -ENOMEM; 2194 return -ENOMEM;
2167 strbuf_addf(result, " %s", buf); 2195 ret = strbuf_addf(result, " %s", buf);
2168 free(buf); 2196 free(buf);
2169 } 2197 }
2170 } 2198 }
2171 strbuf_addch(result, ')'); 2199 if (!ret)
2200 ret = strbuf_addch(result, ')');
2172 2201
2173 return 0; 2202 return ret;
2174} 2203}
2175 2204
2176/* Show an event */ 2205/* Show an event */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 9f688758b000..1259839dbf6d 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1294,6 +1294,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1294{ 1294{
1295 struct available_var_finder *af = data; 1295 struct available_var_finder *af = data;
1296 struct variable_list *vl; 1296 struct variable_list *vl;
1297 struct strbuf buf = STRBUF_INIT;
1297 int tag, ret; 1298 int tag, ret;
1298 1299
1299 vl = &af->vls[af->nvls - 1]; 1300 vl = &af->vls[af->nvls - 1];
@@ -1307,25 +1308,26 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1307 if (ret == 0 || ret == -ERANGE) { 1308 if (ret == 0 || ret == -ERANGE) {
1308 int ret2; 1309 int ret2;
1309 bool externs = !af->child; 1310 bool externs = !af->child;
1310 struct strbuf buf;
1311 1311
1312 strbuf_init(&buf, 64); 1312 if (strbuf_init(&buf, 64) < 0)
1313 goto error;
1313 1314
1314 if (probe_conf.show_location_range) { 1315 if (probe_conf.show_location_range) {
1315 if (!externs) { 1316 if (!externs)
1316 if (ret) 1317 ret2 = strbuf_add(&buf,
1317 strbuf_add(&buf, "[INV]\t", 6); 1318 ret ? "[INV]\t" : "[VAL]\t", 6);
1318 else 1319 else
1319 strbuf_add(&buf, "[VAL]\t", 6); 1320 ret2 = strbuf_add(&buf, "[EXT]\t", 6);
1320 } else 1321 if (ret2)
1321 strbuf_add(&buf, "[EXT]\t", 6); 1322 goto error;
1322 } 1323 }
1323 1324
1324 ret2 = die_get_varname(die_mem, &buf); 1325 ret2 = die_get_varname(die_mem, &buf);
1325 1326
1326 if (!ret2 && probe_conf.show_location_range && 1327 if (!ret2 && probe_conf.show_location_range &&
1327 !externs) { 1328 !externs) {
1328 strbuf_addch(&buf, '\t'); 1329 if (strbuf_addch(&buf, '\t') < 0)
1330 goto error;
1329 ret2 = die_get_var_range(&af->pf.sp_die, 1331 ret2 = die_get_var_range(&af->pf.sp_die,
1330 die_mem, &buf); 1332 die_mem, &buf);
1331 } 1333 }
@@ -1334,8 +1336,8 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1334 if (ret2 == 0) { 1336 if (ret2 == 0) {
1335 strlist__add(vl->vars, 1337 strlist__add(vl->vars,
1336 strbuf_detach(&buf, NULL)); 1338 strbuf_detach(&buf, NULL));
1337 } else 1339 }
1338 strbuf_release(&buf); 1340 strbuf_release(&buf);
1339 } 1341 }
1340 } 1342 }
1341 1343
@@ -1343,6 +1345,10 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1343 return DIE_FIND_CB_CONTINUE; 1345 return DIE_FIND_CB_CONTINUE;
1344 else 1346 else
1345 return DIE_FIND_CB_SIBLING; 1347 return DIE_FIND_CB_SIBLING;
1348error:
1349 strbuf_release(&buf);
1350 pr_debug("Error in strbuf\n");
1351 return DIE_FIND_CB_END;
1346} 1352}
1347 1353
1348/* Add a found vars into available variables list */ 1354/* Add a found vars into available variables list */
diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c
index 01f03242b86a..c6d4ee2de752 100644
--- a/tools/perf/util/quote.c
+++ b/tools/perf/util/quote.c
@@ -17,38 +17,42 @@ static inline int need_bs_quote(char c)
17 return (c == '\'' || c == '!'); 17 return (c == '\'' || c == '!');
18} 18}
19 19
20static void sq_quote_buf(struct strbuf *dst, const char *src) 20static int sq_quote_buf(struct strbuf *dst, const char *src)
21{ 21{
22 char *to_free = NULL; 22 char *to_free = NULL;
23 int ret;
23 24
24 if (dst->buf == src) 25 if (dst->buf == src)
25 to_free = strbuf_detach(dst, NULL); 26 to_free = strbuf_detach(dst, NULL);
26 27
27 strbuf_addch(dst, '\''); 28 ret = strbuf_addch(dst, '\'');
28 while (*src) { 29 while (!ret && *src) {
29 size_t len = strcspn(src, "'!"); 30 size_t len = strcspn(src, "'!");
30 strbuf_add(dst, src, len); 31 ret = strbuf_add(dst, src, len);
31 src += len; 32 src += len;
32 while (need_bs_quote(*src)) { 33 while (!ret && need_bs_quote(*src))
33 strbuf_addstr(dst, "'\\"); 34 ret = strbuf_addf(dst, "'\\%c\'", *src++);
34 strbuf_addch(dst, *src++);
35 strbuf_addch(dst, '\'');
36 }
37 } 35 }
38 strbuf_addch(dst, '\''); 36 if (!ret)
37 ret = strbuf_addch(dst, '\'');
39 free(to_free); 38 free(to_free);
39
40 return ret;
40} 41}
41 42
42void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) 43int sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen)
43{ 44{
44 int i; 45 int i, ret;
45 46
46 /* Copy into destination buffer. */ 47 /* Copy into destination buffer. */
47 strbuf_grow(dst, 255); 48 ret = strbuf_grow(dst, 255);
48 for (i = 0; argv[i]; ++i) { 49 for (i = 0; !ret && argv[i]; ++i) {
49 strbuf_addch(dst, ' '); 50 ret = strbuf_addch(dst, ' ');
50 sq_quote_buf(dst, argv[i]); 51 if (ret)
52 break;
53 ret = sq_quote_buf(dst, argv[i]);
51 if (maxlen && dst->len > maxlen) 54 if (maxlen && dst->len > maxlen)
52 die("Too many or long arguments"); 55 die("Too many or long arguments");
53 } 56 }
57 return ret;
54} 58}
diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h
index 3340c9c4a6ca..e1ec19146fb0 100644
--- a/tools/perf/util/quote.h
+++ b/tools/perf/util/quote.h
@@ -24,6 +24,6 @@
24 * sq_quote() in a real application. 24 * sq_quote() in a real application.
25 */ 25 */
26 26
27void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); 27int sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
28 28
29#endif /* __PERF_QUOTE_H */ 29#endif /* __PERF_QUOTE_H */
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 091bce67844c..1546b749a3a3 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -1062,7 +1062,7 @@ static void set_table_handlers(struct tables *tables)
1062 tables->dbe.cpr = call_path_root__new(); 1062 tables->dbe.cpr = call_path_root__new();
1063 1063
1064 if (!tables->dbe.cpr) 1064 if (!tables->dbe.cpr)
1065 Py_FatalError("failed to create calls processor"); 1065 Py_FatalError("failed to create call path root");
1066 } 1066 }
1067 1067
1068 tables->db_export_mode = true; 1068 tables->db_export_mode = true;
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 4d9b481cf3b6..ffa1d0653861 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -307,6 +307,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,
307 struct perf_counts_values *aggr = &counter->counts->aggr; 307 struct perf_counts_values *aggr = &counter->counts->aggr;
308 struct perf_stat_evsel *ps = counter->priv; 308 struct perf_stat_evsel *ps = counter->priv;
309 u64 *count = counter->counts->aggr.values; 309 u64 *count = counter->counts->aggr.values;
310 u64 val;
310 int i, ret; 311 int i, ret;
311 312
312 aggr->val = aggr->ena = aggr->run = 0; 313 aggr->val = aggr->ena = aggr->run = 0;
@@ -346,7 +347,8 @@ int perf_stat_process_counter(struct perf_stat_config *config,
346 /* 347 /*
347 * Save the full runtime - to allow normalization during printout: 348 * Save the full runtime - to allow normalization during printout:
348 */ 349 */
349 perf_stat__update_shadow_stats(counter, count, 0); 350 val = counter->scale * *count;
351 perf_stat__update_shadow_stats(counter, &val, 0);
350 352
351 return 0; 353 return 0;
352} 354}
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 8fb73295ec34..f95f682aa2b2 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -1,3 +1,4 @@
1#include "debug.h"
1#include "cache.h" 2#include "cache.h"
2#include <linux/kernel.h> 3#include <linux/kernel.h>
3 4
@@ -17,12 +18,13 @@ int prefixcmp(const char *str, const char *prefix)
17 */ 18 */
18char strbuf_slopbuf[1]; 19char strbuf_slopbuf[1];
19 20
20void strbuf_init(struct strbuf *sb, ssize_t hint) 21int strbuf_init(struct strbuf *sb, ssize_t hint)
21{ 22{
22 sb->alloc = sb->len = 0; 23 sb->alloc = sb->len = 0;
23 sb->buf = strbuf_slopbuf; 24 sb->buf = strbuf_slopbuf;
24 if (hint) 25 if (hint)
25 strbuf_grow(sb, hint); 26 return strbuf_grow(sb, hint);
27 return 0;
26} 28}
27 29
28void strbuf_release(struct strbuf *sb) 30void strbuf_release(struct strbuf *sb)
@@ -42,67 +44,104 @@ char *strbuf_detach(struct strbuf *sb, size_t *sz)
42 return res; 44 return res;
43} 45}
44 46
45void strbuf_grow(struct strbuf *sb, size_t extra) 47int strbuf_grow(struct strbuf *sb, size_t extra)
46{ 48{
47 if (sb->len + extra + 1 <= sb->len) 49 char *buf;
48 die("you want to use way too much memory"); 50 size_t nr = sb->len + extra + 1;
49 if (!sb->alloc) 51
50 sb->buf = NULL; 52 if (nr < sb->alloc)
51 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); 53 return 0;
54
55 if (nr <= sb->len)
56 return -E2BIG;
57
58 if (alloc_nr(sb->alloc) > nr)
59 nr = alloc_nr(sb->alloc);
60
61 /*
62 * Note that sb->buf == strbuf_slopbuf if sb->alloc == 0, and it is
63 * a static variable. Thus we have to avoid passing it to realloc.
64 */
65 buf = realloc(sb->alloc ? sb->buf : NULL, nr * sizeof(*buf));
66 if (!buf)
67 return -ENOMEM;
68
69 sb->buf = buf;
70 sb->alloc = nr;
71 return 0;
52} 72}
53 73
54void strbuf_addch(struct strbuf *sb, int c) 74int strbuf_addch(struct strbuf *sb, int c)
55{ 75{
56 strbuf_grow(sb, 1); 76 int ret = strbuf_grow(sb, 1);
77 if (ret)
78 return ret;
79
57 sb->buf[sb->len++] = c; 80 sb->buf[sb->len++] = c;
58 sb->buf[sb->len] = '\0'; 81 sb->buf[sb->len] = '\0';
82 return 0;
59} 83}
60 84
61void strbuf_add(struct strbuf *sb, const void *data, size_t len) 85int strbuf_add(struct strbuf *sb, const void *data, size_t len)
62{ 86{
63 strbuf_grow(sb, len); 87 int ret = strbuf_grow(sb, len);
88 if (ret)
89 return ret;
90
64 memcpy(sb->buf + sb->len, data, len); 91 memcpy(sb->buf + sb->len, data, len);
65 strbuf_setlen(sb, sb->len + len); 92 return strbuf_setlen(sb, sb->len + len);
66} 93}
67 94
68static void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap) 95static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
69{ 96{
70 int len; 97 int len, ret;
71 va_list ap_saved; 98 va_list ap_saved;
72 99
73 if (!strbuf_avail(sb)) 100 if (!strbuf_avail(sb)) {
74 strbuf_grow(sb, 64); 101 ret = strbuf_grow(sb, 64);
102 if (ret)
103 return ret;
104 }
75 105
76 va_copy(ap_saved, ap); 106 va_copy(ap_saved, ap);
77 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 107 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
78 if (len < 0) 108 if (len < 0)
79 die("your vsnprintf is broken"); 109 return len;
80 if (len > strbuf_avail(sb)) { 110 if (len > strbuf_avail(sb)) {
81 strbuf_grow(sb, len); 111 ret = strbuf_grow(sb, len);
112 if (ret)
113 return ret;
82 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved); 114 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
83 va_end(ap_saved); 115 va_end(ap_saved);
84 if (len > strbuf_avail(sb)) { 116 if (len > strbuf_avail(sb)) {
85 die("this should not happen, your vsnprintf is broken"); 117 pr_debug("this should not happen, your vsnprintf is broken");
118 return -EINVAL;
86 } 119 }
87 } 120 }
88 strbuf_setlen(sb, sb->len + len); 121 return strbuf_setlen(sb, sb->len + len);
89} 122}
90 123
91void strbuf_addf(struct strbuf *sb, const char *fmt, ...) 124int strbuf_addf(struct strbuf *sb, const char *fmt, ...)
92{ 125{
93 va_list ap; 126 va_list ap;
127 int ret;
94 128
95 va_start(ap, fmt); 129 va_start(ap, fmt);
96 strbuf_addv(sb, fmt, ap); 130 ret = strbuf_addv(sb, fmt, ap);
97 va_end(ap); 131 va_end(ap);
132 return ret;
98} 133}
99 134
100ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) 135ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
101{ 136{
102 size_t oldlen = sb->len; 137 size_t oldlen = sb->len;
103 size_t oldalloc = sb->alloc; 138 size_t oldalloc = sb->alloc;
139 int ret;
140
141 ret = strbuf_grow(sb, hint ? hint : 8192);
142 if (ret)
143 return ret;
104 144
105 strbuf_grow(sb, hint ? hint : 8192);
106 for (;;) { 145 for (;;) {
107 ssize_t cnt; 146 ssize_t cnt;
108 147
@@ -112,12 +151,14 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
112 strbuf_release(sb); 151 strbuf_release(sb);
113 else 152 else
114 strbuf_setlen(sb, oldlen); 153 strbuf_setlen(sb, oldlen);
115 return -1; 154 return cnt;
116 } 155 }
117 if (!cnt) 156 if (!cnt)
118 break; 157 break;
119 sb->len += cnt; 158 sb->len += cnt;
120 strbuf_grow(sb, 8192); 159 ret = strbuf_grow(sb, 8192);
160 if (ret)
161 return ret;
121 } 162 }
122 163
123 sb->buf[sb->len] = '\0'; 164 sb->buf[sb->len] = '\0';
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index ab9be0fbbd40..54b409297d4a 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -51,7 +51,7 @@ struct strbuf {
51#define STRBUF_INIT { 0, 0, strbuf_slopbuf } 51#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
52 52
53/*----- strbuf life cycle -----*/ 53/*----- strbuf life cycle -----*/
54void strbuf_init(struct strbuf *buf, ssize_t hint); 54int strbuf_init(struct strbuf *buf, ssize_t hint);
55void strbuf_release(struct strbuf *buf); 55void strbuf_release(struct strbuf *buf);
56char *strbuf_detach(struct strbuf *buf, size_t *); 56char *strbuf_detach(struct strbuf *buf, size_t *);
57 57
@@ -60,26 +60,31 @@ static inline ssize_t strbuf_avail(const struct strbuf *sb) {
60 return sb->alloc ? sb->alloc - sb->len - 1 : 0; 60 return sb->alloc ? sb->alloc - sb->len - 1 : 0;
61} 61}
62 62
63void strbuf_grow(struct strbuf *buf, size_t); 63int strbuf_grow(struct strbuf *buf, size_t);
64 64
65static inline void strbuf_setlen(struct strbuf *sb, size_t len) { 65static inline int strbuf_setlen(struct strbuf *sb, size_t len) {
66 if (!sb->alloc) 66 int ret;
67 strbuf_grow(sb, 0); 67 if (!sb->alloc) {
68 ret = strbuf_grow(sb, 0);
69 if (ret)
70 return ret;
71 }
68 assert(len < sb->alloc); 72 assert(len < sb->alloc);
69 sb->len = len; 73 sb->len = len;
70 sb->buf[len] = '\0'; 74 sb->buf[len] = '\0';
75 return 0;
71} 76}
72 77
73/*----- add data in your buffer -----*/ 78/*----- add data in your buffer -----*/
74void strbuf_addch(struct strbuf *sb, int c); 79int strbuf_addch(struct strbuf *sb, int c);
75 80
76void strbuf_add(struct strbuf *buf, const void *, size_t); 81int strbuf_add(struct strbuf *buf, const void *, size_t);
77static inline void strbuf_addstr(struct strbuf *sb, const char *s) { 82static inline int strbuf_addstr(struct strbuf *sb, const char *s) {
78 strbuf_add(sb, s, strlen(s)); 83 return strbuf_add(sb, s, strlen(s));
79} 84}
80 85
81__attribute__((format(printf,2,3))) 86__attribute__((format(printf,2,3)))
82void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 87int strbuf_addf(struct strbuf *sb, const char *fmt, ...);
83 88
84/* XXX: if read fails, any partial read is undone */ 89/* XXX: if read fails, any partial read is undone */
85ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 90ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 415c4f6d98fd..2946295ca502 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -301,7 +301,7 @@ static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
301 301
302 if (ip < s->start) 302 if (ip < s->start)
303 n = n->rb_left; 303 n = n->rb_left;
304 else if (ip >= s->end) 304 else if (ip > s->end || (ip == s->end && ip != s->start))
305 n = n->rb_right; 305 n = n->rb_right;
306 else 306 else
307 return s; 307 return s;
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 619ba2061b62..01c9433de7ef 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -507,7 +507,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
507 "needed for --call-graph fp\n"); 507 "needed for --call-graph fp\n");
508 break; 508 break;
509 509
510#ifdef HAVE_DWARF_UNWIND_SUPPORT
511 /* Dwarf style */ 510 /* Dwarf style */
512 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) { 511 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
513 const unsigned long default_stack_dump_size = 8192; 512 const unsigned long default_stack_dump_size = 8192;
@@ -523,7 +522,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
523 ret = get_stack_size(tok, &size); 522 ret = get_stack_size(tok, &size);
524 param->dump_size = size; 523 param->dump_size = size;
525 } 524 }
526#endif /* HAVE_DWARF_UNWIND_SUPPORT */
527 } else if (!strncmp(name, "lbr", sizeof("lbr"))) { 525 } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
528 if (!strtok_r(NULL, ",", &saveptr)) { 526 if (!strtok_r(NULL, ",", &saveptr)) {
529 param->record_mode = CALLCHAIN_LBR; 527 param->record_mode = CALLCHAIN_LBR;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 88f607af1f47..7651633a8dc7 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -160,12 +160,6 @@ static inline char *gitstrchrnul(const char *s, int c)
160} 160}
161#endif 161#endif
162 162
163/*
164 * Wrappers:
165 */
166void *xrealloc(void *ptr, size_t size) __attribute__((weak));
167
168
169static inline void *zalloc(size_t size) 163static inline void *zalloc(size_t size)
170{ 164{
171 return calloc(1, size); 165 return calloc(1, size);
diff --git a/tools/perf/util/wrapper.c b/tools/perf/util/wrapper.c
deleted file mode 100644
index 5f1a07c4b87b..000000000000
--- a/tools/perf/util/wrapper.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Various trivial helper wrappers around standard functions
3 */
4#include "cache.h"
5
6/*
7 * There's no pack memory to release - but stay close to the Git
8 * version so wrap this away:
9 */
10static inline void release_pack_memory(size_t size __maybe_unused,
11 int flag __maybe_unused)
12{
13}
14
15void *xrealloc(void *ptr, size_t size)
16{
17 void *ret = realloc(ptr, size);
18 if (!ret && !size)
19 ret = realloc(ptr, 1);
20 if (!ret) {
21 release_pack_memory(size, -1);
22 ret = realloc(ptr, size);
23 if (!ret && !size)
24 ret = realloc(ptr, 1);
25 if (!ret)
26 die("Out of memory, realloc failed");
27 }
28 return ret;
29}