aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-02-16 02:45:56 -0500
committerIngo Molnar <mingo@kernel.org>2016-02-16 02:45:56 -0500
commitfe7a2eaa71c55aadbf95d01d32df8dccc0db0646 (patch)
tree1f5f60ba774358e953c1b688c7e7c246be936117 /tools
parenta7636d9ecfa3ab7800a7c04c1f89378229eff609 (diff)
parent1ad826bad5bd0b6ccfb203f78c70302b764df0be (diff)
Merge tag 'perf-core-for-mingo' 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: - Do not print trailing spaces in the hists browser (top, report) to avoid line wrapping issues when long C++ demangled functions are sampled (Arnaldo Carvalho de Melo) - Allow 'perf config' to show --system or --user settings (Taeung Song) - Add better warning about the need to install the audit-lib-python package when using perf python scripts (Taeung Song) - Fix symbol resolution when kernel modules files are only in the build id cache (~/.debug) (Wang Nan) Build fixes: - Fix 'perf test' build on older systems where 'signal' is reserved (Arnaldo Carvalho de Melo) Infrastructure changes: - Free the terms list_head in parse_events__free_terms(), also unlink the entries when deleting them (Wang Nan) - Fix releasing event_class in 'perf data' fixing integration with libbabeltrace (Wang Nan) - Add EXTRA_LDFLAGS option to Makefile (Zubair Lutfullah Kakakhel) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-config.txt14
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c2
-rw-r--r--tools/perf/builtin-config.c27
-rw-r--r--tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py5
-rw-r--r--tools/perf/tests/bp_signal.c12
-rw-r--r--tools/perf/tests/parse-events.c2
-rw-r--r--tools/perf/ui/browsers/hists.c27
-rw-r--r--tools/perf/ui/stdio/hist.c1
-rw-r--r--tools/perf/util/build-id.c44
-rw-r--r--tools/perf/util/build-id.h1
-rw-r--r--tools/perf/util/cache.h3
-rw-r--r--tools/perf/util/config.c4
-rw-r--r--tools/perf/util/data-convert-bt.c18
-rw-r--r--tools/perf/util/hist.c21
-rw-r--r--tools/perf/util/hist.h5
-rw-r--r--tools/perf/util/parse-events.c17
-rw-r--r--tools/perf/util/parse-events.h3
-rw-r--r--tools/perf/util/parse-events.y8
-rw-r--r--tools/perf/util/pmu.c2
-rw-r--r--tools/perf/util/sort.c23
-rw-r--r--tools/perf/util/symbol.c4
22 files changed, 200 insertions, 45 deletions
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index c7158bfb1649..15949e2a7805 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf config' -l | --list 11'perf config' [<file-option>] -l | --list
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
@@ -21,6 +21,14 @@ OPTIONS
21--list:: 21--list::
22 Show current config variables, name and value, for all sections. 22 Show current config variables, name and value, for all sections.
23 23
24--user::
25 For writing and reading options: write to user
26 '$HOME/.perfconfig' file or read it.
27
28--system::
29 For writing and reading options: write to system-wide
30 '$(sysconfdir)/perfconfig' or read it.
31
24CONFIGURATION FILE 32CONFIGURATION FILE
25------------------ 33------------------
26 34
@@ -30,6 +38,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration.
30The file '$(sysconfdir)/perfconfig' can be used to 38The file '$(sysconfdir)/perfconfig' can be used to
31store a system-wide default configuration. 39store a system-wide default configuration.
32 40
41When reading or writing, the values are read from the system and user
42configuration files by default, and options '--system' and '--user'
43can be used to tell the command to read from or write to only that location.
44
33Syntax 45Syntax
34~~~~~~ 46~~~~~~
35 47
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d404117810a7..4a4fad4182f5 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -139,6 +139,8 @@ $(call allow-override,CC,$(CROSS_COMPILE)gcc)
139$(call allow-override,AR,$(CROSS_COMPILE)ar) 139$(call allow-override,AR,$(CROSS_COMPILE)ar)
140$(call allow-override,LD,$(CROSS_COMPILE)ld) 140$(call allow-override,LD,$(CROSS_COMPILE)ld)
141 141
142LD += $(EXTRA_LDFLAGS)
143
142PKG_CONFIG = $(CROSS_COMPILE)pkg-config 144PKG_CONFIG = $(CROSS_COMPILE)pkg-config
143 145
144RM = rm -f 146RM = rm -f
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index 6f7d453b0e32..a3395179c9ee 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -89,7 +89,7 @@ static int intel_pt_parse_terms_with_default(struct list_head *formats,
89 89
90 *config = attr.config; 90 *config = attr.config;
91out_free: 91out_free:
92 parse_events__free_terms(terms); 92 parse_events_terms__delete(terms);
93 return err; 93 return err;
94} 94}
95 95
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index f04e804a9fad..c42448ed5dfe 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -13,8 +13,10 @@
13#include "util/util.h" 13#include "util/util.h"
14#include "util/debug.h" 14#include "util/debug.h"
15 15
16static bool use_system_config, use_user_config;
17
16static const char * const config_usage[] = { 18static const char * const config_usage[] = {
17 "perf config [options]", 19 "perf config [<file-option>] [options]",
18 NULL 20 NULL
19}; 21};
20 22
@@ -25,6 +27,8 @@ enum actions {
25static struct option config_options[] = { 27static struct option config_options[] = {
26 OPT_SET_UINT('l', "list", &actions, 28 OPT_SET_UINT('l', "list", &actions,
27 "show current config variables", ACTION_LIST), 29 "show current config variables", ACTION_LIST),
30 OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
31 OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
28 OPT_END() 32 OPT_END()
29}; 33};
30 34
@@ -42,10 +46,23 @@ static int show_config(const char *key, const char *value,
42int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) 46int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
43{ 47{
44 int ret = 0; 48 int ret = 0;
49 char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
45 50
46 argc = parse_options(argc, argv, config_options, config_usage, 51 argc = parse_options(argc, argv, config_options, config_usage,
47 PARSE_OPT_STOP_AT_NON_OPTION); 52 PARSE_OPT_STOP_AT_NON_OPTION);
48 53
54 if (use_system_config && use_user_config) {
55 pr_err("Error: only one config file at a time\n");
56 parse_options_usage(config_usage, config_options, "user", 0);
57 parse_options_usage(NULL, config_options, "system", 0);
58 return -1;
59 }
60
61 if (use_system_config)
62 config_exclusive_filename = perf_etc_perfconfig();
63 else if (use_user_config)
64 config_exclusive_filename = user_config;
65
49 switch (actions) { 66 switch (actions) {
50 case ACTION_LIST: 67 case ACTION_LIST:
51 if (argc) { 68 if (argc) {
@@ -53,9 +70,13 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
53 parse_options_usage(config_usage, config_options, "l", 1); 70 parse_options_usage(config_usage, config_options, "l", 1);
54 } else { 71 } else {
55 ret = perf_config(show_config, NULL); 72 ret = perf_config(show_config, NULL);
56 if (ret < 0) 73 if (ret < 0) {
74 const char * config_filename = config_exclusive_filename;
75 if (!config_exclusive_filename)
76 config_filename = user_config;
57 pr_err("Nothing configured, " 77 pr_err("Nothing configured, "
58 "please check your ~/.perfconfig file\n"); 78 "please check your %s \n", config_filename);
79 }
59 } 80 }
60 break; 81 break;
61 default: 82 default:
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
index 15c8400240fd..1d95009592eb 100644
--- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
+++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
@@ -71,7 +71,10 @@ try:
71except: 71except:
72 if not audit_package_warned: 72 if not audit_package_warned:
73 audit_package_warned = True 73 audit_package_warned = True
74 print "Install the audit-libs-python package to get syscall names" 74 print "Install the audit-libs-python package to get syscall names.\n" \
75 "For example:\n # apt-get install python-audit (Ubuntu)" \
76 "\n # yum install audit-libs-python (Fedora)" \
77 "\n etc.\n"
75 78
76def syscall_name(id): 79def syscall_name(id):
77 try: 80 try:
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index 1d1bb489b4e8..e7664fe3bd33 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -103,7 +103,7 @@ static void sig_handler(int signum __maybe_unused,
103 } 103 }
104} 104}
105 105
106static int __event(bool is_x, void *addr, int signal) 106static int __event(bool is_x, void *addr, int sig)
107{ 107{
108 struct perf_event_attr pe; 108 struct perf_event_attr pe;
109 int fd; 109 int fd;
@@ -133,7 +133,7 @@ static int __event(bool is_x, void *addr, int signal)
133 } 133 }
134 134
135 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); 135 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
136 fcntl(fd, F_SETSIG, signal); 136 fcntl(fd, F_SETSIG, sig);
137 fcntl(fd, F_SETOWN, getpid()); 137 fcntl(fd, F_SETOWN, getpid());
138 138
139 ioctl(fd, PERF_EVENT_IOC_RESET, 0); 139 ioctl(fd, PERF_EVENT_IOC_RESET, 0);
@@ -141,14 +141,14 @@ static int __event(bool is_x, void *addr, int signal)
141 return fd; 141 return fd;
142} 142}
143 143
144static int bp_event(void *addr, int signal) 144static int bp_event(void *addr, int sig)
145{ 145{
146 return __event(true, addr, signal); 146 return __event(true, addr, sig);
147} 147}
148 148
149static int wp_event(void *addr, int signal) 149static int wp_event(void *addr, int sig)
150{ 150{
151 return __event(false, addr, signal); 151 return __event(false, addr, sig);
152} 152}
153 153
154static long long bp_count(int fd) 154static long long bp_count(int fd)
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index abe8849d1d70..6648274f4601 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1666,7 +1666,7 @@ static int test_term(struct terms_test *t)
1666 } 1666 }
1667 1667
1668 ret = t->check(&terms); 1668 ret = t->check(&terms);
1669 parse_events__free_terms(&terms); 1669 parse_events_terms__purge(&terms);
1670 1670
1671 return ret; 1671 return ret;
1672} 1672}
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a5a5390476ac..1819771243f9 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1061,7 +1061,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1061 struct hist_entry *entry, 1061 struct hist_entry *entry,
1062 unsigned short row) 1062 unsigned short row)
1063{ 1063{
1064 char s[256];
1065 int printed = 0; 1064 int printed = 0;
1066 int width = browser->b.width; 1065 int width = browser->b.width;
1067 char folded_sign = ' '; 1066 char folded_sign = ' ';
@@ -1086,16 +1085,18 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1086 .folded_sign = folded_sign, 1085 .folded_sign = folded_sign,
1087 .current_entry = current_entry, 1086 .current_entry = current_entry,
1088 }; 1087 };
1089 struct perf_hpp hpp = {
1090 .buf = s,
1091 .size = sizeof(s),
1092 .ptr = &arg,
1093 };
1094 int column = 0; 1088 int column = 0;
1095 1089
1096 hist_browser__gotorc(browser, row, 0); 1090 hist_browser__gotorc(browser, row, 0);
1097 1091
1098 hists__for_each_format(browser->hists, fmt) { 1092 hists__for_each_format(browser->hists, fmt) {
1093 char s[2048];
1094 struct perf_hpp hpp = {
1095 .buf = s,
1096 .size = sizeof(s),
1097 .ptr = &arg,
1098 };
1099
1099 if (perf_hpp__should_skip(fmt, entry->hists) || 1100 if (perf_hpp__should_skip(fmt, entry->hists) ||
1100 column++ < browser->b.horiz_scroll) 1101 column++ < browser->b.horiz_scroll)
1101 continue; 1102 continue;
@@ -1120,11 +1121,18 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1120 } 1121 }
1121 1122
1122 if (fmt->color) { 1123 if (fmt->color) {
1123 width -= fmt->color(fmt, &hpp, entry); 1124 int ret = fmt->color(fmt, &hpp, entry);
1125 hist_entry__snprintf_alignment(entry, &hpp, fmt, ret);
1126 /*
1127 * fmt->color() already used ui_browser to
1128 * print the non alignment bits, skip it (+ret):
1129 */
1130 ui_browser__printf(&browser->b, "%s", s + ret);
1124 } else { 1131 } else {
1125 width -= fmt->entry(fmt, &hpp, entry); 1132 hist_entry__snprintf_alignment(entry, &hpp, fmt, fmt->entry(fmt, &hpp, entry));
1126 ui_browser__printf(&browser->b, "%s", s); 1133 ui_browser__printf(&browser->b, "%s", s);
1127 } 1134 }
1135 width -= hpp.buf - s;
1128 } 1136 }
1129 1137
1130 /* The scroll bar isn't being used */ 1138 /* The scroll bar isn't being used */
@@ -1452,9 +1460,10 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
1452 first = false; 1460 first = false;
1453 1461
1454 ret = fmt->entry(fmt, &hpp, he); 1462 ret = fmt->entry(fmt, &hpp, he);
1463 ret = hist_entry__snprintf_alignment(he, &hpp, fmt, ret);
1455 advance_hpp(&hpp, ret); 1464 advance_hpp(&hpp, ret);
1456 } 1465 }
1457 printed += fprintf(fp, "%s\n", rtrim(s)); 1466 printed += fprintf(fp, "%s\n", s);
1458 1467
1459 if (folded_sign == '-') 1468 if (folded_sign == '-')
1460 printed += hist_browser__fprintf_callchain(browser, he, fp); 1469 printed += hist_browser__fprintf_callchain(browser, he, fp);
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 1a6e8f7f38c4..87b022ff03d8 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -403,6 +403,7 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
403 else 403 else
404 ret = fmt->entry(fmt, hpp, he); 404 ret = fmt->entry(fmt, hpp, he);
405 405
406 ret = hist_entry__snprintf_alignment(he, hpp, fmt, ret);
406 advance_hpp(hpp, ret); 407 advance_hpp(hpp, ret);
407 } 408 }
408 409
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index b28100ee1732..f1479eeef7da 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -166,6 +166,50 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
166 return build_id__filename(build_id_hex, bf, size); 166 return build_id__filename(build_id_hex, bf, size);
167} 167}
168 168
169bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
170{
171 char *id_name, *ch;
172 struct stat sb;
173
174 id_name = dso__build_id_filename(dso, bf, size);
175 if (!id_name)
176 goto err;
177 if (access(id_name, F_OK))
178 goto err;
179 if (lstat(id_name, &sb) == -1)
180 goto err;
181 if ((size_t)sb.st_size > size - 1)
182 goto err;
183 if (readlink(id_name, bf, size - 1) < 0)
184 goto err;
185
186 bf[sb.st_size] = '\0';
187
188 /*
189 * link should be:
190 * ../../lib/modules/4.4.0-rc4/kernel/net/ipv4/netfilter/nf_nat_ipv4.ko/a09fe3eb3147dafa4e3b31dbd6257e4d696bdc92
191 */
192 ch = strrchr(bf, '/');
193 if (!ch)
194 goto err;
195 if (ch - 3 < bf)
196 goto err;
197
198 return strncmp(".ko", ch - 3, 3) == 0;
199err:
200 /*
201 * If dso__build_id_filename work, get id_name again,
202 * because id_name points to bf and is broken.
203 */
204 if (id_name)
205 id_name = dso__build_id_filename(dso, bf, size);
206 pr_err("Invalid build id: %s\n", id_name ? :
207 dso->long_name ? :
208 dso->short_name ? :
209 "[unknown]");
210 return false;
211}
212
169#define dsos__for_each_with_build_id(pos, head) \ 213#define dsos__for_each_with_build_id(pos, head) \
170 list_for_each_entry(pos, head, node) \ 214 list_for_each_entry(pos, head, node) \
171 if (!pos->has_build_id) \ 215 if (!pos->has_build_id) \
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 27a14a8a945b..64af3e20610d 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -16,6 +16,7 @@ int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id);
16int filename__sprintf_build_id(const char *pathname, char *sbuild_id); 16int filename__sprintf_build_id(const char *pathname, char *sbuild_id);
17 17
18char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); 18char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size);
19bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size);
19 20
20int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, 21int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
21 struct perf_sample *sample, struct perf_evsel *evsel, 22 struct perf_sample *sample, struct perf_evsel *evsel,
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 07b5d63947b1..3ca453f0c51f 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -23,6 +23,8 @@
23#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" 23#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
24#define PERF_PAGER_ENVIRONMENT "PERF_PAGER" 24#define PERF_PAGER_ENVIRONMENT "PERF_PAGER"
25 25
26extern const char *config_exclusive_filename;
27
26typedef int (*config_fn_t)(const char *, const char *, void *); 28typedef int (*config_fn_t)(const char *, const char *, void *);
27extern int perf_default_config(const char *, const char *, void *); 29extern int perf_default_config(const char *, const char *, void *);
28extern int perf_config(config_fn_t fn, void *); 30extern int perf_config(config_fn_t fn, void *);
@@ -31,6 +33,7 @@ extern u64 perf_config_u64(const char *, const char *);
31extern int perf_config_bool(const char *, const char *); 33extern int perf_config_bool(const char *, const char *);
32extern int config_error_nonbool(const char *); 34extern int config_error_nonbool(const char *);
33extern const char *perf_config_dirname(const char *, const char *); 35extern const char *perf_config_dirname(const char *, const char *);
36extern const char *perf_etc_perfconfig(void);
34 37
35char *alias_lookup(const char *alias); 38char *alias_lookup(const char *alias);
36int split_cmdline(char *cmdline, const char ***argv); 39int split_cmdline(char *cmdline, const char ***argv);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index d3e12e30e1d5..4e727635476e 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -26,7 +26,7 @@ static const char *config_file_name;
26static int config_linenr; 26static int config_linenr;
27static int config_file_eof; 27static int config_file_eof;
28 28
29static const char *config_exclusive_filename; 29const char *config_exclusive_filename;
30 30
31static int get_next_char(void) 31static int get_next_char(void)
32{ 32{
@@ -434,7 +434,7 @@ static int perf_config_from_file(config_fn_t fn, const char *filename, void *dat
434 return ret; 434 return ret;
435} 435}
436 436
437static const char *perf_etc_perfconfig(void) 437const char *perf_etc_perfconfig(void)
438{ 438{
439 static const char *system_wide; 439 static const char *system_wide;
440 if (!system_wide) 440 if (!system_wide)
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 34cd1e4039d3..b722e57d5a87 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -858,6 +858,23 @@ static int setup_events(struct ctf_writer *cw, struct perf_session *session)
858 return 0; 858 return 0;
859} 859}
860 860
861static void cleanup_events(struct perf_session *session)
862{
863 struct perf_evlist *evlist = session->evlist;
864 struct perf_evsel *evsel;
865
866 evlist__for_each(evlist, evsel) {
867 struct evsel_priv *priv;
868
869 priv = evsel->priv;
870 bt_ctf_event_class_put(priv->event_class);
871 zfree(&evsel->priv);
872 }
873
874 perf_evlist__delete(evlist);
875 session->evlist = NULL;
876}
877
861static int setup_streams(struct ctf_writer *cw, struct perf_session *session) 878static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
862{ 879{
863 struct ctf_stream **stream; 880 struct ctf_stream **stream;
@@ -1171,6 +1188,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, bool force)
1171 (double) c.events_size / 1024.0 / 1024.0, 1188 (double) c.events_size / 1024.0 / 1024.0,
1172 c.events_count); 1189 c.events_count);
1173 1190
1191 cleanup_events(session);
1174 perf_session__delete(session); 1192 perf_session__delete(session);
1175 ctf_writer__cleanup(cw); 1193 ctf_writer__cleanup(cw);
1176 1194
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 12f2d794dc28..561e9473a915 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1015,6 +1015,27 @@ void hist_entry__delete(struct hist_entry *he)
1015} 1015}
1016 1016
1017/* 1017/*
1018 * If this is not the last column, then we need to pad it according to the
1019 * pre-calculated max lenght for this column, otherwise don't bother adding
1020 * spaces because that would break viewing this with, for instance, 'less',
1021 * that would show tons of trailing spaces when a long C++ demangled method
1022 * names is sampled.
1023*/
1024int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
1025 struct perf_hpp_fmt *fmt, int printed)
1026{
1027 if (!list_is_last(&fmt->list, &he->hists->hpp_list->fields)) {
1028 const int width = fmt->width(fmt, hpp, hists_to_evsel(he->hists));
1029 if (printed < width) {
1030 advance_hpp(hpp, printed);
1031 printed = scnprintf(hpp->buf, hpp->size, "%-*s", width - printed, " ");
1032 }
1033 }
1034
1035 return printed;
1036}
1037
1038/*
1018 * collapse the histogram 1039 * collapse the histogram
1019 */ 1040 */
1020 1041
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 1c7544a8fe1a..840b6d6aa44f 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -122,11 +122,16 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
122int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, 122int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
123 int max_stack_depth, void *arg); 123 int max_stack_depth, void *arg);
124 124
125struct perf_hpp;
126struct perf_hpp_fmt;
127
125int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right); 128int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
126int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right); 129int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
127int hist_entry__transaction_len(void); 130int hist_entry__transaction_len(void);
128int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size, 131int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
129 struct hists *hists); 132 struct hists *hists);
133int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
134 struct perf_hpp_fmt *fmt, int printed);
130void hist_entry__delete(struct hist_entry *he); 135void hist_entry__delete(struct hist_entry *he);
131 136
132void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog); 137void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 813d9b272c81..e5583fd4e7bd 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1386,8 +1386,7 @@ int parse_events_terms(struct list_head *terms, const char *str)
1386 return 0; 1386 return 0;
1387 } 1387 }
1388 1388
1389 if (data.terms) 1389 parse_events_terms__delete(data.terms);
1390 parse_events__free_terms(data.terms);
1391 return ret; 1390 return ret;
1392} 1391}
1393 1392
@@ -2068,12 +2067,22 @@ int parse_events_term__clone(struct parse_events_term **new,
2068 term->err_term, term->err_val); 2067 term->err_term, term->err_val);
2069} 2068}
2070 2069
2071void parse_events__free_terms(struct list_head *terms) 2070void parse_events_terms__purge(struct list_head *terms)
2072{ 2071{
2073 struct parse_events_term *term, *h; 2072 struct parse_events_term *term, *h;
2074 2073
2075 list_for_each_entry_safe(term, h, terms, list) 2074 list_for_each_entry_safe(term, h, terms, list) {
2075 list_del_init(&term->list);
2076 free(term); 2076 free(term);
2077 }
2078}
2079
2080void parse_events_terms__delete(struct list_head *terms)
2081{
2082 if (!terms)
2083 return;
2084 parse_events_terms__purge(terms);
2085 free(terms);
2077} 2086}
2078 2087
2079void parse_events_evlist_error(struct parse_events_evlist *data, 2088void parse_events_evlist_error(struct parse_events_evlist *data,
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index f1a6db107241..53628bf3da67 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -115,7 +115,8 @@ int parse_events_term__sym_hw(struct parse_events_term **term,
115 char *config, unsigned idx); 115 char *config, unsigned idx);
116int parse_events_term__clone(struct parse_events_term **new, 116int parse_events_term__clone(struct parse_events_term **new,
117 struct parse_events_term *term); 117 struct parse_events_term *term);
118void parse_events__free_terms(struct list_head *terms); 118void parse_events_terms__delete(struct list_head *terms);
119void parse_events_terms__purge(struct list_head *terms);
119int parse_events__modifier_event(struct list_head *list, char *str, bool add); 120int parse_events__modifier_event(struct list_head *list, char *str, bool add);
120int parse_events__modifier_group(struct list_head *list, char *event_mod); 121int parse_events__modifier_group(struct list_head *list, char *event_mod);
121int parse_events_name(struct list_head *list, char *name); 122int parse_events_name(struct list_head *list, char *name);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index ad379968d4c1..c0eac88ef474 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -218,7 +218,7 @@ PE_NAME '/' event_config '/'
218 218
219 ALLOC_LIST(list); 219 ALLOC_LIST(list);
220 ABORT_ON(parse_events_add_pmu(data, list, $1, $3)); 220 ABORT_ON(parse_events_add_pmu(data, list, $1, $3));
221 parse_events__free_terms($3); 221 parse_events_terms__delete($3);
222 $$ = list; 222 $$ = list;
223} 223}
224| 224|
@@ -246,7 +246,7 @@ PE_KERNEL_PMU_EVENT sep_dc
246 246
247 ALLOC_LIST(list); 247 ALLOC_LIST(list);
248 ABORT_ON(parse_events_add_pmu(data, list, "cpu", head)); 248 ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
249 parse_events__free_terms(head); 249 parse_events_terms__delete(head);
250 $$ = list; 250 $$ = list;
251} 251}
252| 252|
@@ -266,7 +266,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
266 266
267 ALLOC_LIST(list); 267 ALLOC_LIST(list);
268 ABORT_ON(parse_events_add_pmu(data, list, "cpu", head)); 268 ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
269 parse_events__free_terms(head); 269 parse_events_terms__delete(head);
270 $$ = list; 270 $$ = list;
271} 271}
272 272
@@ -285,7 +285,7 @@ value_sym '/' event_config '/'
285 285
286 ALLOC_LIST(list); 286 ALLOC_LIST(list);
287 ABORT_ON(parse_events_add_numeric(data, list, type, config, $3)); 287 ABORT_ON(parse_events_add_numeric(data, list, type, config, $3));
288 parse_events__free_terms($3); 288 parse_events_terms__delete($3);
289 $$ = list; 289 $$ = list;
290} 290}
291| 291|
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 41a9c875e492..cf59fbaee491 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -354,7 +354,7 @@ static int pmu_alias_terms(struct perf_pmu_alias *alias,
354 list_for_each_entry(term, &alias->terms, list) { 354 list_for_each_entry(term, &alias->terms, list) {
355 ret = parse_events_term__clone(&cloned, term); 355 ret = parse_events_term__clone(&cloned, term);
356 if (ret) { 356 if (ret) {
357 parse_events__free_terms(&list); 357 parse_events_terms__purge(&list);
358 return ret; 358 return ret;
359 } 359 }
360 list_add_tail(&cloned->list, &list); 360 list_add_tail(&cloned->list, &list);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index de620f7f40f4..de715756f281 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -28,7 +28,15 @@ int sort__has_socket = 0;
28int sort__has_thread = 0; 28int sort__has_thread = 0;
29enum sort_mode sort__mode = SORT_MODE__NORMAL; 29enum sort_mode sort__mode = SORT_MODE__NORMAL;
30 30
31 31/*
32 * Replaces all occurrences of a char used with the:
33 *
34 * -t, --field-separator
35 *
36 * option, that uses a special separator character and don't pad with spaces,
37 * replacing all occurances of this separator in symbol names (and other
38 * output) with a '.' character, that thus it's the only non valid separator.
39*/
32static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) 40static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
33{ 41{
34 int n; 42 int n;
@@ -247,10 +255,8 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
247 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); 255 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
248 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", 256 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
249 ip - map->unmap_ip(map, sym->start)); 257 ip - map->unmap_ip(map, sym->start));
250 ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
251 width - ret, "");
252 } else { 258 } else {
253 ret += repsep_snprintf(bf + ret, size - ret, "%-*s", 259 ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
254 width - ret, 260 width - ret,
255 sym->name); 261 sym->name);
256 } 262 }
@@ -258,14 +264,9 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
258 size_t len = BITS_PER_LONG / 4; 264 size_t len = BITS_PER_LONG / 4;
259 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", 265 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx",
260 len, ip); 266 len, ip);
261 ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
262 width - ret, "");
263 } 267 }
264 268
265 if (ret > width) 269 return ret;
266 bf[width] = '\0';
267
268 return width;
269} 270}
270 271
271static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, 272static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
@@ -811,7 +812,7 @@ static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
811 else 812 else
812 out = "No"; 813 out = "No";
813 814
814 return repsep_snprintf(bf, size, "%-*s", width, out); 815 return repsep_snprintf(bf, size, "%.*s", width, out);
815} 816}
816 817
817static int64_t 818static int64_t
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 90cedfa30e43..e7588dc91518 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1529,6 +1529,10 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1529 if (!runtime_ss && syms_ss) 1529 if (!runtime_ss && syms_ss)
1530 runtime_ss = syms_ss; 1530 runtime_ss = syms_ss;
1531 1531
1532 if (syms_ss && syms_ss->type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
1533 if (dso__build_id_is_kmod(dso, name, PATH_MAX))
1534 kmod = true;
1535
1532 if (syms_ss) 1536 if (syms_ss)
1533 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod); 1537 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod);
1534 else 1538 else