diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/build/Makefile.feature | 2 | ||||
-rw-r--r-- | tools/build/feature/Makefile | 4 | ||||
-rw-r--r-- | tools/build/feature/test-all.c | 5 | ||||
-rw-r--r-- | tools/build/feature/test-dwarf_getlocations.c | 12 | ||||
-rw-r--r-- | tools/lib/traceevent/parse-filter.c | 4 | ||||
-rw-r--r-- | tools/perf/arch/x86/util/dwarf-regs.c | 8 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 70 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 7 | ||||
-rw-r--r-- | tools/perf/config/Makefile | 6 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.c | 9 | ||||
-rw-r--r-- | tools/perf/util/event.c | 12 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 23 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 60 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 3 | ||||
-rw-r--r-- | tools/perf/util/thread_map.c | 8 |
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 | |||
30 | FEATURE_TESTS_BASIC := \ | 30 | FEATURE_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 | ||
79 | FEATURE_DISPLAY ?= \ | 80 | FEATURE_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 | |||
4 | int 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__ | ||
66 | static const struct pt_regs_offset x86_32_regoffset_table[] = { | 68 | static 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 | ||
78 | static const struct pt_regs_offset x86_64_regoffset_table[] = { | 82 | static 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 | */ |
1691 | int find_scripts(char **scripts_array, char **scripts_path_array) | 1689 | int 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 | ||
1757 | static char *get_script_path(const char *script_root, const char *suffix) | 1755 | static 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) { |
531 | try_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 |
273 | endif # NO_LIBELF | 279 | endif # 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 | ||
1085 | int 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: | |||
2345 | bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | 2345 | bool 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 | ||
147 | static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) | 147 | static 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: | |||
1905 | int is_valid_tracepoint(const char *event_string) | 1905 | int 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 | ||
2446 | static char *setup_overhead(char *keys) | 2446 | static 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; |