aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/build/Makefile.feature2
-rw-r--r--tools/build/feature/Makefile4
-rw-r--r--tools/build/feature/test-all.c5
-rw-r--r--tools/build/feature/test-dwarf_getlocations.c12
-rw-r--r--tools/lib/traceevent/parse-filter.c4
-rw-r--r--tools/perf/arch/x86/util/dwarf-regs.c8
-rw-r--r--tools/perf/builtin-script.c70
-rw-r--r--tools/perf/builtin-stat.c7
-rw-r--r--tools/perf/config/Makefile6
-rw-r--r--tools/perf/util/dwarf-aux.c9
-rw-r--r--tools/perf/util/event.c12
-rw-r--r--tools/perf/util/evsel.c23
-rw-r--r--tools/perf/util/parse-events.c60
-rw-r--r--tools/perf/util/sort.c3
-rw-r--r--tools/perf/util/thread_map.c8
15 files changed, 148 insertions, 85 deletions
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 6b7707270aa3..9f878619077a 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -30,6 +30,7 @@ endef
30FEATURE_TESTS_BASIC := \ 30FEATURE_TESTS_BASIC := \
31 backtrace \ 31 backtrace \
32 dwarf \ 32 dwarf \
33 dwarf_getlocations \
33 fortify-source \ 34 fortify-source \
34 sync-compare-and-swap \ 35 sync-compare-and-swap \
35 glibc \ 36 glibc \
@@ -78,6 +79,7 @@ endif
78 79
79FEATURE_DISPLAY ?= \ 80FEATURE_DISPLAY ?= \
80 dwarf \ 81 dwarf \
82 dwarf_getlocations \
81 glibc \ 83 glibc \
82 gtk2 \ 84 gtk2 \
83 libaudit \ 85 libaudit \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index c5f4c417428d..4ae94dbfdab9 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -3,6 +3,7 @@ FILES= \
3 test-backtrace.bin \ 3 test-backtrace.bin \
4 test-bionic.bin \ 4 test-bionic.bin \
5 test-dwarf.bin \ 5 test-dwarf.bin \
6 test-dwarf_getlocations.bin \
6 test-fortify-source.bin \ 7 test-fortify-source.bin \
7 test-sync-compare-and-swap.bin \ 8 test-sync-compare-and-swap.bin \
8 test-glibc.bin \ 9 test-glibc.bin \
@@ -82,6 +83,9 @@ endif
82$(OUTPUT)test-dwarf.bin: 83$(OUTPUT)test-dwarf.bin:
83 $(BUILD) $(DWARFLIBS) 84 $(BUILD) $(DWARFLIBS)
84 85
86$(OUTPUT)test-dwarf_getlocations.bin:
87 $(BUILD) $(DWARFLIBS)
88
85$(OUTPUT)test-libelf-mmap.bin: 89$(OUTPUT)test-libelf-mmap.bin:
86 $(BUILD) -lelf 90 $(BUILD) -lelf
87 91
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index e499a36c1e4a..a282e8cb84f3 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -41,6 +41,10 @@
41# include "test-dwarf.c" 41# include "test-dwarf.c"
42#undef main 42#undef main
43 43
44#define main main_test_dwarf_getlocations
45# include "test-dwarf_getlocations.c"
46#undef main
47
44#define main main_test_libelf_getphdrnum 48#define main main_test_libelf_getphdrnum
45# include "test-libelf-getphdrnum.c" 49# include "test-libelf-getphdrnum.c"
46#undef main 50#undef main
@@ -143,6 +147,7 @@ int main(int argc, char *argv[])
143 main_test_libelf_mmap(); 147 main_test_libelf_mmap();
144 main_test_glibc(); 148 main_test_glibc();
145 main_test_dwarf(); 149 main_test_dwarf();
150 main_test_dwarf_getlocations();
146 main_test_libelf_getphdrnum(); 151 main_test_libelf_getphdrnum();
147 main_test_libunwind(); 152 main_test_libunwind();
148 main_test_libaudit(); 153 main_test_libaudit();
diff --git a/tools/build/feature/test-dwarf_getlocations.c b/tools/build/feature/test-dwarf_getlocations.c
new file mode 100644
index 000000000000..70162699dd43
--- /dev/null
+++ b/tools/build/feature/test-dwarf_getlocations.c
@@ -0,0 +1,12 @@
1#include <stdlib.h>
2#include <elfutils/libdw.h>
3
4int main(void)
5{
6 Dwarf_Addr base, start, end;
7 Dwarf_Attribute attr;
8 Dwarf_Op *op;
9 size_t nops;
10 ptrdiff_t offset = 0;
11 return (int)dwarf_getlocations(&attr, offset, &base, &start, &end, &op, &nops);
12}
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 0144b3d1bb77..88cccea3ca99 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -1164,11 +1164,11 @@ process_filter(struct event_format *event, struct filter_arg **parg,
1164 current_op = current_exp; 1164 current_op = current_exp;
1165 1165
1166 ret = collapse_tree(current_op, parg, error_str); 1166 ret = collapse_tree(current_op, parg, error_str);
1167 /* collapse_tree() may free current_op, and updates parg accordingly */
1168 current_op = NULL;
1167 if (ret < 0) 1169 if (ret < 0)
1168 goto fail; 1170 goto fail;
1169 1171
1170 *parg = current_op;
1171
1172 free(token); 1172 free(token);
1173 return 0; 1173 return 0;
1174 1174
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
index 9223c164e545..1f86ee8fb831 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -63,6 +63,8 @@ struct pt_regs_offset {
63# define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)} 63# define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
64#endif 64#endif
65 65
66/* TODO: switching by dwarf address size */
67#ifndef __x86_64__
66static const struct pt_regs_offset x86_32_regoffset_table[] = { 68static const struct pt_regs_offset x86_32_regoffset_table[] = {
67 REG_OFFSET_NAME_32("%ax", eax), 69 REG_OFFSET_NAME_32("%ax", eax),
68 REG_OFFSET_NAME_32("%cx", ecx), 70 REG_OFFSET_NAME_32("%cx", ecx),
@@ -75,6 +77,8 @@ static const struct pt_regs_offset x86_32_regoffset_table[] = {
75 REG_OFFSET_END, 77 REG_OFFSET_END,
76}; 78};
77 79
80#define regoffset_table x86_32_regoffset_table
81#else
78static const struct pt_regs_offset x86_64_regoffset_table[] = { 82static const struct pt_regs_offset x86_64_regoffset_table[] = {
79 REG_OFFSET_NAME_64("%ax", rax), 83 REG_OFFSET_NAME_64("%ax", rax),
80 REG_OFFSET_NAME_64("%dx", rdx), 84 REG_OFFSET_NAME_64("%dx", rdx),
@@ -95,11 +99,7 @@ static const struct pt_regs_offset x86_64_regoffset_table[] = {
95 REG_OFFSET_END, 99 REG_OFFSET_END,
96}; 100};
97 101
98/* TODO: switching by dwarf address size */
99#ifdef __x86_64__
100#define regoffset_table x86_64_regoffset_table 102#define regoffset_table x86_64_regoffset_table
101#else
102#define regoffset_table x86_32_regoffset_table
103#endif 103#endif
104 104
105/* Minus 1 for the ending REG_OFFSET_END */ 105/* Minus 1 for the ending REG_OFFSET_END */
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 3770c3dffe5e..52826696c852 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1415,21 +1415,19 @@ static int is_directory(const char *base_path, const struct dirent *dent)
1415 return S_ISDIR(st.st_mode); 1415 return S_ISDIR(st.st_mode);
1416} 1416}
1417 1417
1418#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ 1418#define for_each_lang(scripts_path, scripts_dir, lang_dirent) \
1419 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ 1419 while ((lang_dirent = readdir(scripts_dir)) != NULL) \
1420 lang_next) \ 1420 if ((lang_dirent->d_type == DT_DIR || \
1421 if ((lang_dirent.d_type == DT_DIR || \ 1421 (lang_dirent->d_type == DT_UNKNOWN && \
1422 (lang_dirent.d_type == DT_UNKNOWN && \ 1422 is_directory(scripts_path, lang_dirent))) && \
1423 is_directory(scripts_path, &lang_dirent))) && \ 1423 (strcmp(lang_dirent->d_name, ".")) && \
1424 (strcmp(lang_dirent.d_name, ".")) && \ 1424 (strcmp(lang_dirent->d_name, "..")))
1425 (strcmp(lang_dirent.d_name, ".."))) 1425
1426 1426#define for_each_script(lang_path, lang_dir, script_dirent) \
1427#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ 1427 while ((script_dirent = readdir(lang_dir)) != NULL) \
1428 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ 1428 if (script_dirent->d_type != DT_DIR && \
1429 script_next) \ 1429 (script_dirent->d_type != DT_UNKNOWN || \
1430 if (script_dirent.d_type != DT_DIR && \ 1430 !is_directory(lang_path, script_dirent)))
1431 (script_dirent.d_type != DT_UNKNOWN || \
1432 !is_directory(lang_path, &script_dirent)))
1433 1431
1434 1432
1435#define RECORD_SUFFIX "-record" 1433#define RECORD_SUFFIX "-record"
@@ -1575,7 +1573,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
1575 const char *s __maybe_unused, 1573 const char *s __maybe_unused,
1576 int unset __maybe_unused) 1574 int unset __maybe_unused)
1577{ 1575{
1578 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1576 struct dirent *script_dirent, *lang_dirent;
1579 char scripts_path[MAXPATHLEN]; 1577 char scripts_path[MAXPATHLEN];
1580 DIR *scripts_dir, *lang_dir; 1578 DIR *scripts_dir, *lang_dir;
1581 char script_path[MAXPATHLEN]; 1579 char script_path[MAXPATHLEN];
@@ -1590,19 +1588,19 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
1590 if (!scripts_dir) 1588 if (!scripts_dir)
1591 return -1; 1589 return -1;
1592 1590
1593 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 1591 for_each_lang(scripts_path, scripts_dir, lang_dirent) {
1594 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1592 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
1595 lang_dirent.d_name); 1593 lang_dirent->d_name);
1596 lang_dir = opendir(lang_path); 1594 lang_dir = opendir(lang_path);
1597 if (!lang_dir) 1595 if (!lang_dir)
1598 continue; 1596 continue;
1599 1597
1600 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1598 for_each_script(lang_path, lang_dir, script_dirent) {
1601 script_root = get_script_root(&script_dirent, REPORT_SUFFIX); 1599 script_root = get_script_root(script_dirent, REPORT_SUFFIX);
1602 if (script_root) { 1600 if (script_root) {
1603 desc = script_desc__findnew(script_root); 1601 desc = script_desc__findnew(script_root);
1604 snprintf(script_path, MAXPATHLEN, "%s/%s", 1602 snprintf(script_path, MAXPATHLEN, "%s/%s",
1605 lang_path, script_dirent.d_name); 1603 lang_path, script_dirent->d_name);
1606 read_script_info(desc, script_path); 1604 read_script_info(desc, script_path);
1607 free(script_root); 1605 free(script_root);
1608 } 1606 }
@@ -1690,7 +1688,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
1690 */ 1688 */
1691int find_scripts(char **scripts_array, char **scripts_path_array) 1689int find_scripts(char **scripts_array, char **scripts_path_array)
1692{ 1690{
1693 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1691 struct dirent *script_dirent, *lang_dirent;
1694 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 1692 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
1695 DIR *scripts_dir, *lang_dir; 1693 DIR *scripts_dir, *lang_dir;
1696 struct perf_session *session; 1694 struct perf_session *session;
@@ -1713,9 +1711,9 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
1713 return -1; 1711 return -1;
1714 } 1712 }
1715 1713
1716 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 1714 for_each_lang(scripts_path, scripts_dir, lang_dirent) {
1717 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, 1715 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
1718 lang_dirent.d_name); 1716 lang_dirent->d_name);
1719#ifdef NO_LIBPERL 1717#ifdef NO_LIBPERL
1720 if (strstr(lang_path, "perl")) 1718 if (strstr(lang_path, "perl"))
1721 continue; 1719 continue;
@@ -1729,16 +1727,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
1729 if (!lang_dir) 1727 if (!lang_dir)
1730 continue; 1728 continue;
1731 1729
1732 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1730 for_each_script(lang_path, lang_dir, script_dirent) {
1733 /* Skip those real time scripts: xxxtop.p[yl] */ 1731 /* Skip those real time scripts: xxxtop.p[yl] */
1734 if (strstr(script_dirent.d_name, "top.")) 1732 if (strstr(script_dirent->d_name, "top."))
1735 continue; 1733 continue;
1736 sprintf(scripts_path_array[i], "%s/%s", lang_path, 1734 sprintf(scripts_path_array[i], "%s/%s", lang_path,
1737 script_dirent.d_name); 1735 script_dirent->d_name);
1738 temp = strchr(script_dirent.d_name, '.'); 1736 temp = strchr(script_dirent->d_name, '.');
1739 snprintf(scripts_array[i], 1737 snprintf(scripts_array[i],
1740 (temp - script_dirent.d_name) + 1, 1738 (temp - script_dirent->d_name) + 1,
1741 "%s", script_dirent.d_name); 1739 "%s", script_dirent->d_name);
1742 1740
1743 if (check_ev_match(lang_path, 1741 if (check_ev_match(lang_path,
1744 scripts_array[i], session)) 1742 scripts_array[i], session))
@@ -1756,7 +1754,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
1756 1754
1757static char *get_script_path(const char *script_root, const char *suffix) 1755static char *get_script_path(const char *script_root, const char *suffix)
1758{ 1756{
1759 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1757 struct dirent *script_dirent, *lang_dirent;
1760 char scripts_path[MAXPATHLEN]; 1758 char scripts_path[MAXPATHLEN];
1761 char script_path[MAXPATHLEN]; 1759 char script_path[MAXPATHLEN];
1762 DIR *scripts_dir, *lang_dir; 1760 DIR *scripts_dir, *lang_dir;
@@ -1769,21 +1767,21 @@ static char *get_script_path(const char *script_root, const char *suffix)
1769 if (!scripts_dir) 1767 if (!scripts_dir)
1770 return NULL; 1768 return NULL;
1771 1769
1772 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 1770 for_each_lang(scripts_path, scripts_dir, lang_dirent) {
1773 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1771 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
1774 lang_dirent.d_name); 1772 lang_dirent->d_name);
1775 lang_dir = opendir(lang_path); 1773 lang_dir = opendir(lang_path);
1776 if (!lang_dir) 1774 if (!lang_dir)
1777 continue; 1775 continue;
1778 1776
1779 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1777 for_each_script(lang_path, lang_dir, script_dirent) {
1780 __script_root = get_script_root(&script_dirent, suffix); 1778 __script_root = get_script_root(script_dirent, suffix);
1781 if (__script_root && !strcmp(script_root, __script_root)) { 1779 if (__script_root && !strcmp(script_root, __script_root)) {
1782 free(__script_root); 1780 free(__script_root);
1783 closedir(lang_dir); 1781 closedir(lang_dir);
1784 closedir(scripts_dir); 1782 closedir(scripts_dir);
1785 snprintf(script_path, MAXPATHLEN, "%s/%s", 1783 snprintf(script_path, MAXPATHLEN, "%s/%s",
1786 lang_path, script_dirent.d_name); 1784 lang_path, script_dirent->d_name);
1787 return strdup(script_path); 1785 return strdup(script_path);
1788 } 1786 }
1789 free(__script_root); 1787 free(__script_root);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 1f19f2f999c8..307e8a1a003c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -528,6 +528,7 @@ static int __run_perf_stat(int argc, const char **argv)
528 perf_evlist__set_leader(evsel_list); 528 perf_evlist__set_leader(evsel_list);
529 529
530 evlist__for_each(evsel_list, counter) { 530 evlist__for_each(evsel_list, counter) {
531try_again:
531 if (create_perf_stat_counter(counter) < 0) { 532 if (create_perf_stat_counter(counter) < 0) {
532 /* 533 /*
533 * PPC returns ENXIO for HW counters until 2.6.37 534 * PPC returns ENXIO for HW counters until 2.6.37
@@ -544,7 +545,11 @@ static int __run_perf_stat(int argc, const char **argv)
544 if ((counter->leader != counter) || 545 if ((counter->leader != counter) ||
545 !(counter->leader->nr_members > 1)) 546 !(counter->leader->nr_members > 1))
546 continue; 547 continue;
547 } 548 } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
549 if (verbose)
550 ui__warning("%s\n", msg);
551 goto try_again;
552 }
548 553
549 perf_evsel__open_strerror(counter, &target, 554 perf_evsel__open_strerror(counter, &target,
550 errno, msg, sizeof(msg)); 555 errno, msg, sizeof(msg));
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index f7d7f5a1cad5..6f8f6430f2bf 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -268,6 +268,12 @@ else
268 ifneq ($(feature-dwarf), 1) 268 ifneq ($(feature-dwarf), 1)
269 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); 269 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
270 NO_DWARF := 1 270 NO_DWARF := 1
271 else
272 ifneq ($(feature-dwarf_getlocations), 1)
273 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157);
274 else
275 CFLAGS += -DHAVE_DWARF_GETLOCATIONS
276 endif # dwarf_getlocations
271 endif # Dwarf support 277 endif # Dwarf support
272 endif # libelf support 278 endif # libelf support
273endif # NO_LIBELF 279endif # NO_LIBELF
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 577e600c8eb1..aea189b41cc8 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -959,6 +959,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
959 return 0; 959 return 0;
960} 960}
961 961
962#ifdef HAVE_DWARF_GETLOCATIONS
962/** 963/**
963 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE 964 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE
964 * @sp_die: a subprogram DIE 965 * @sp_die: a subprogram DIE
@@ -1080,3 +1081,11 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
1080 1081
1081 return ret; 1082 return ret;
1082} 1083}
1084#else
1085int die_get_var_range(Dwarf_Die *sp_die __maybe_unused,
1086 Dwarf_Die *vr_die __maybe_unused,
1087 struct strbuf *buf __maybe_unused)
1088{
1089 return -ENOTSUP;
1090}
1091#endif
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index dad55d04ffdd..edcf4ed4e99c 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -433,7 +433,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,
433{ 433{
434 char filename[PATH_MAX]; 434 char filename[PATH_MAX];
435 DIR *tasks; 435 DIR *tasks;
436 struct dirent dirent, *next; 436 struct dirent *dirent;
437 pid_t tgid, ppid; 437 pid_t tgid, ppid;
438 int rc = 0; 438 int rc = 0;
439 439
@@ -462,11 +462,11 @@ static int __event__synthesize_thread(union perf_event *comm_event,
462 return 0; 462 return 0;
463 } 463 }
464 464
465 while (!readdir_r(tasks, &dirent, &next) && next) { 465 while ((dirent = readdir(tasks)) != NULL) {
466 char *end; 466 char *end;
467 pid_t _pid; 467 pid_t _pid;
468 468
469 _pid = strtol(dirent.d_name, &end, 10); 469 _pid = strtol(dirent->d_name, &end, 10);
470 if (*end) 470 if (*end)
471 continue; 471 continue;
472 472
@@ -575,7 +575,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
575{ 575{
576 DIR *proc; 576 DIR *proc;
577 char proc_path[PATH_MAX]; 577 char proc_path[PATH_MAX];
578 struct dirent dirent, *next; 578 struct dirent *dirent;
579 union perf_event *comm_event, *mmap_event, *fork_event; 579 union perf_event *comm_event, *mmap_event, *fork_event;
580 int err = -1; 580 int err = -1;
581 581
@@ -600,9 +600,9 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
600 if (proc == NULL) 600 if (proc == NULL)
601 goto out_free_fork; 601 goto out_free_fork;
602 602
603 while (!readdir_r(proc, &dirent, &next) && next) { 603 while ((dirent = readdir(proc)) != NULL) {
604 char *end; 604 char *end;
605 pid_t pid = strtol(dirent.d_name, &end, 10); 605 pid_t pid = strtol(dirent->d_name, &end, 10);
606 606
607 if (*end) /* only interested in proper numerical dirents */ 607 if (*end) /* only interested in proper numerical dirents */
608 continue; 608 continue;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 738ce226002b..645dc1828836 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2345,6 +2345,8 @@ out:
2345bool perf_evsel__fallback(struct perf_evsel *evsel, int err, 2345bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
2346 char *msg, size_t msgsize) 2346 char *msg, size_t msgsize)
2347{ 2347{
2348 int paranoid;
2349
2348 if ((err == ENOENT || err == ENXIO || err == ENODEV) && 2350 if ((err == ENOENT || err == ENXIO || err == ENODEV) &&
2349 evsel->attr.type == PERF_TYPE_HARDWARE && 2351 evsel->attr.type == PERF_TYPE_HARDWARE &&
2350 evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES) { 2352 evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES) {
@@ -2364,6 +2366,22 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
2364 2366
2365 zfree(&evsel->name); 2367 zfree(&evsel->name);
2366 return true; 2368 return true;
2369 } else if (err == EACCES && !evsel->attr.exclude_kernel &&
2370 (paranoid = perf_event_paranoid()) > 1) {
2371 const char *name = perf_evsel__name(evsel);
2372 char *new_name;
2373
2374 if (asprintf(&new_name, "%s%su", name, strchr(name, ':') ? "" : ":") < 0)
2375 return false;
2376
2377 if (evsel->name)
2378 free(evsel->name);
2379 evsel->name = new_name;
2380 scnprintf(msg, msgsize,
2381"kernel.perf_event_paranoid=%d, trying to fall back to excluding kernel samples", paranoid);
2382 evsel->attr.exclude_kernel = 1;
2383
2384 return true;
2367 } 2385 }
2368 2386
2369 return false; 2387 return false;
@@ -2382,12 +2400,13 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2382 "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n" 2400 "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n"
2383 "which controls use of the performance events system by\n" 2401 "which controls use of the performance events system by\n"
2384 "unprivileged users (without CAP_SYS_ADMIN).\n\n" 2402 "unprivileged users (without CAP_SYS_ADMIN).\n\n"
2385 "The default value is 1:\n\n" 2403 "The current value is %d:\n\n"
2386 " -1: Allow use of (almost) all events by all users\n" 2404 " -1: Allow use of (almost) all events by all users\n"
2387 ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" 2405 ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n"
2388 ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" 2406 ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n"
2389 ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN", 2407 ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN",
2390 target->system_wide ? "system-wide " : ""); 2408 target->system_wide ? "system-wide " : "",
2409 perf_event_paranoid());
2391 case ENOENT: 2410 case ENOENT:
2392 return scnprintf(msg, size, "The %s event is not supported.", 2411 return scnprintf(msg, size, "The %s event is not supported.",
2393 perf_evsel__name(evsel)); 2412 perf_evsel__name(evsel));
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4c19d5e79d8c..bcbc983d4b12 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -138,11 +138,11 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
138#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 138#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
139#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 139#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
140 140
141#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 141#define for_each_subsystem(sys_dir, sys_dirent) \
142 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 142 while ((sys_dirent = readdir(sys_dir)) != NULL) \
143 if (sys_dirent.d_type == DT_DIR && \ 143 if (sys_dirent->d_type == DT_DIR && \
144 (strcmp(sys_dirent.d_name, ".")) && \ 144 (strcmp(sys_dirent->d_name, ".")) && \
145 (strcmp(sys_dirent.d_name, ".."))) 145 (strcmp(sys_dirent->d_name, "..")))
146 146
147static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 147static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
148{ 148{
@@ -159,12 +159,12 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
159 return 0; 159 return 0;
160} 160}
161 161
162#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 162#define for_each_event(sys_dirent, evt_dir, evt_dirent) \
163 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 163 while ((evt_dirent = readdir(evt_dir)) != NULL) \
164 if (evt_dirent.d_type == DT_DIR && \ 164 if (evt_dirent->d_type == DT_DIR && \
165 (strcmp(evt_dirent.d_name, ".")) && \ 165 (strcmp(evt_dirent->d_name, ".")) && \
166 (strcmp(evt_dirent.d_name, "..")) && \ 166 (strcmp(evt_dirent->d_name, "..")) && \
167 (!tp_event_has_id(&sys_dirent, &evt_dirent))) 167 (!tp_event_has_id(sys_dirent, evt_dirent)))
168 168
169#define MAX_EVENT_LENGTH 512 169#define MAX_EVENT_LENGTH 512
170 170
@@ -173,7 +173,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
173{ 173{
174 struct tracepoint_path *path = NULL; 174 struct tracepoint_path *path = NULL;
175 DIR *sys_dir, *evt_dir; 175 DIR *sys_dir, *evt_dir;
176 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 176 struct dirent *sys_dirent, *evt_dirent;
177 char id_buf[24]; 177 char id_buf[24];
178 int fd; 178 int fd;
179 u64 id; 179 u64 id;
@@ -184,18 +184,18 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
184 if (!sys_dir) 184 if (!sys_dir)
185 return NULL; 185 return NULL;
186 186
187 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 187 for_each_subsystem(sys_dir, sys_dirent) {
188 188
189 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 189 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
190 sys_dirent.d_name); 190 sys_dirent->d_name);
191 evt_dir = opendir(dir_path); 191 evt_dir = opendir(dir_path);
192 if (!evt_dir) 192 if (!evt_dir)
193 continue; 193 continue;
194 194
195 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 195 for_each_event(sys_dirent, evt_dir, evt_dirent) {
196 196
197 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 197 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
198 evt_dirent.d_name); 198 evt_dirent->d_name);
199 fd = open(evt_path, O_RDONLY); 199 fd = open(evt_path, O_RDONLY);
200 if (fd < 0) 200 if (fd < 0)
201 continue; 201 continue;
@@ -220,9 +220,9 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
220 free(path); 220 free(path);
221 return NULL; 221 return NULL;
222 } 222 }
223 strncpy(path->system, sys_dirent.d_name, 223 strncpy(path->system, sys_dirent->d_name,
224 MAX_EVENT_LENGTH); 224 MAX_EVENT_LENGTH);
225 strncpy(path->name, evt_dirent.d_name, 225 strncpy(path->name, evt_dirent->d_name,
226 MAX_EVENT_LENGTH); 226 MAX_EVENT_LENGTH);
227 return path; 227 return path;
228 } 228 }
@@ -1812,7 +1812,7 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
1812 bool name_only) 1812 bool name_only)
1813{ 1813{
1814 DIR *sys_dir, *evt_dir; 1814 DIR *sys_dir, *evt_dir;
1815 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1815 struct dirent *sys_dirent, *evt_dirent;
1816 char evt_path[MAXPATHLEN]; 1816 char evt_path[MAXPATHLEN];
1817 char dir_path[MAXPATHLEN]; 1817 char dir_path[MAXPATHLEN];
1818 char **evt_list = NULL; 1818 char **evt_list = NULL;
@@ -1830,20 +1830,20 @@ restart:
1830 goto out_close_sys_dir; 1830 goto out_close_sys_dir;
1831 } 1831 }
1832 1832
1833 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1833 for_each_subsystem(sys_dir, sys_dirent) {
1834 if (subsys_glob != NULL && 1834 if (subsys_glob != NULL &&
1835 !strglobmatch(sys_dirent.d_name, subsys_glob)) 1835 !strglobmatch(sys_dirent->d_name, subsys_glob))
1836 continue; 1836 continue;
1837 1837
1838 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1838 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
1839 sys_dirent.d_name); 1839 sys_dirent->d_name);
1840 evt_dir = opendir(dir_path); 1840 evt_dir = opendir(dir_path);
1841 if (!evt_dir) 1841 if (!evt_dir)
1842 continue; 1842 continue;
1843 1843
1844 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1844 for_each_event(sys_dirent, evt_dir, evt_dirent) {
1845 if (event_glob != NULL && 1845 if (event_glob != NULL &&
1846 !strglobmatch(evt_dirent.d_name, event_glob)) 1846 !strglobmatch(evt_dirent->d_name, event_glob))
1847 continue; 1847 continue;
1848 1848
1849 if (!evt_num_known) { 1849 if (!evt_num_known) {
@@ -1852,7 +1852,7 @@ restart:
1852 } 1852 }
1853 1853
1854 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1854 snprintf(evt_path, MAXPATHLEN, "%s:%s",
1855 sys_dirent.d_name, evt_dirent.d_name); 1855 sys_dirent->d_name, evt_dirent->d_name);
1856 1856
1857 evt_list[evt_i] = strdup(evt_path); 1857 evt_list[evt_i] = strdup(evt_path);
1858 if (evt_list[evt_i] == NULL) 1858 if (evt_list[evt_i] == NULL)
@@ -1905,7 +1905,7 @@ out_close_sys_dir:
1905int is_valid_tracepoint(const char *event_string) 1905int is_valid_tracepoint(const char *event_string)
1906{ 1906{
1907 DIR *sys_dir, *evt_dir; 1907 DIR *sys_dir, *evt_dir;
1908 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1908 struct dirent *sys_dirent, *evt_dirent;
1909 char evt_path[MAXPATHLEN]; 1909 char evt_path[MAXPATHLEN];
1910 char dir_path[MAXPATHLEN]; 1910 char dir_path[MAXPATHLEN];
1911 1911
@@ -1913,17 +1913,17 @@ int is_valid_tracepoint(const char *event_string)
1913 if (!sys_dir) 1913 if (!sys_dir)
1914 return 0; 1914 return 0;
1915 1915
1916 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1916 for_each_subsystem(sys_dir, sys_dirent) {
1917 1917
1918 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1918 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
1919 sys_dirent.d_name); 1919 sys_dirent->d_name);
1920 evt_dir = opendir(dir_path); 1920 evt_dir = opendir(dir_path);
1921 if (!evt_dir) 1921 if (!evt_dir)
1922 continue; 1922 continue;
1923 1923
1924 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1924 for_each_event(sys_dirent, evt_dir, evt_dirent) {
1925 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1925 snprintf(evt_path, MAXPATHLEN, "%s:%s",
1926 sys_dirent.d_name, evt_dirent.d_name); 1926 sys_dirent->d_name, evt_dirent->d_name);
1927 if (!strcmp(evt_path, event_string)) { 1927 if (!strcmp(evt_path, event_string)) {
1928 closedir(evt_dir); 1928 closedir(evt_dir);
1929 closedir(sys_dir); 1929 closedir(sys_dir);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 47966a1618c7..f5ba111cd9fb 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2445,6 +2445,9 @@ static char *prefix_if_not_in(const char *pre, char *str)
2445 2445
2446static char *setup_overhead(char *keys) 2446static char *setup_overhead(char *keys)
2447{ 2447{
2448 if (sort__mode == SORT_MODE__DIFF)
2449 return keys;
2450
2448 keys = prefix_if_not_in("overhead", keys); 2451 keys = prefix_if_not_in("overhead", keys);
2449 2452
2450 if (symbol_conf.cumulate_callchain) 2453 if (symbol_conf.cumulate_callchain)
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 08afc6909953..267112b4e3db 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -94,7 +94,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
94 DIR *proc; 94 DIR *proc;
95 int max_threads = 32, items, i; 95 int max_threads = 32, items, i;
96 char path[256]; 96 char path[256];
97 struct dirent dirent, *next, **namelist = NULL; 97 struct dirent *dirent, **namelist = NULL;
98 struct thread_map *threads = thread_map__alloc(max_threads); 98 struct thread_map *threads = thread_map__alloc(max_threads);
99 99
100 if (threads == NULL) 100 if (threads == NULL)
@@ -107,16 +107,16 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
107 threads->nr = 0; 107 threads->nr = 0;
108 atomic_set(&threads->refcnt, 1); 108 atomic_set(&threads->refcnt, 1);
109 109
110 while (!readdir_r(proc, &dirent, &next) && next) { 110 while ((dirent = readdir(proc)) != NULL) {
111 char *end; 111 char *end;
112 bool grow = false; 112 bool grow = false;
113 struct stat st; 113 struct stat st;
114 pid_t pid = strtol(dirent.d_name, &end, 10); 114 pid_t pid = strtol(dirent->d_name, &end, 10);
115 115
116 if (*end) /* only interested in proper numerical dirents */ 116 if (*end) /* only interested in proper numerical dirents */
117 continue; 117 continue;
118 118
119 snprintf(path, sizeof(path), "/proc/%s", dirent.d_name); 119 snprintf(path, sizeof(path), "/proc/%s", dirent->d_name);
120 120
121 if (stat(path, &st) != 0) 121 if (stat(path, &st) != 0)
122 continue; 122 continue;