diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-12-18 03:37:51 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-12-18 03:37:51 -0500 |
commit | b21daaede100d102b1687a403df74be0a02031af (patch) | |
tree | cdc7fe583ee8d4837a1bc2246d861a69828edbce | |
parent | 0d76ded582c178d3cca55c9112eceb5b0f12f558 (diff) | |
parent | 1843b4e057b7717db21a3ad96fa16d6b4ee8f6c4 (diff) |
Merge tag 'perf-core-for-mingo-2.1' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements from Arnaldo Carvalho de Melo:
User visible changes:
- Add record.build-id config option to 'perf record', to allow configuring
in the ~/.perfconfig file if and how build-ids should be processed, allowing
a permanent setting for options such as -B and -N: (Namhyung Kim)
$ perf record -h -B -N
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-B, --no-buildid do not collect buildids in perf.data
-N, --no-buildid-cache do not update the buildid cache
$
Infrastructure changes:
- Move code for options parsing and subcommand handling from tools/perf/
to tools/lib/subcmd/, so that it can be used by other tools/ living
utilities (Josh Poimboeuf)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
85 files changed, 1103 insertions, 582 deletions
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 37ff4c9f92f1..6c0519de765d 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature | |||
@@ -7,7 +7,7 @@ endif | |||
7 | 7 | ||
8 | feature_check = $(eval $(feature_check_code)) | 8 | feature_check = $(eval $(feature_check_code)) |
9 | define feature_check_code | 9 | define feature_check_code |
10 | feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) | 10 | feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) |
11 | endef | 11 | endef |
12 | 12 | ||
13 | feature_set = $(eval $(feature_set_code)) | 13 | feature_set = $(eval $(feature_set_code)) |
@@ -101,7 +101,6 @@ ifeq ($(feature-all), 1) | |||
101 | # | 101 | # |
102 | $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat))) | 102 | $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat))) |
103 | else | 103 | else |
104 | $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C $(feature_dir) $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1) | ||
105 | $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) | 104 | $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) |
106 | endif | 105 | endif |
107 | 106 | ||
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index cea04ce9f35c..bf8f0352264d 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | FILES= \ | 1 | FILES= \ |
3 | test-all.bin \ | 2 | test-all.bin \ |
4 | test-backtrace.bin \ | 3 | test-backtrace.bin \ |
@@ -38,38 +37,40 @@ FILES= \ | |||
38 | test-bpf.bin \ | 37 | test-bpf.bin \ |
39 | test-get_cpuid.bin | 38 | test-get_cpuid.bin |
40 | 39 | ||
40 | FILES := $(addprefix $(OUTPUT),$(FILES)) | ||
41 | |||
41 | CC := $(CROSS_COMPILE)gcc -MD | 42 | CC := $(CROSS_COMPILE)gcc -MD |
42 | PKG_CONFIG := $(CROSS_COMPILE)pkg-config | 43 | PKG_CONFIG := $(CROSS_COMPILE)pkg-config |
43 | 44 | ||
44 | all: $(FILES) | 45 | all: $(FILES) |
45 | 46 | ||
46 | __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS) | 47 | __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $@ $(patsubst %.bin,%.c,$(@F)) $(LDFLAGS) |
47 | BUILD = $(__BUILD) > $(OUTPUT)$(@:.bin=.make.output) 2>&1 | 48 | BUILD = $(__BUILD) > $(@:.bin=.make.output) 2>&1 |
48 | 49 | ||
49 | ############################### | 50 | ############################### |
50 | 51 | ||
51 | test-all.bin: | 52 | $(OUTPUT)test-all.bin: |
52 | $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma | 53 | $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma |
53 | 54 | ||
54 | test-hello.bin: | 55 | $(OUTPUT)test-hello.bin: |
55 | $(BUILD) | 56 | $(BUILD) |
56 | 57 | ||
57 | test-pthread-attr-setaffinity-np.bin: | 58 | $(OUTPUT)test-pthread-attr-setaffinity-np.bin: |
58 | $(BUILD) -D_GNU_SOURCE -lpthread | 59 | $(BUILD) -D_GNU_SOURCE -lpthread |
59 | 60 | ||
60 | test-stackprotector-all.bin: | 61 | $(OUTPUT)test-stackprotector-all.bin: |
61 | $(BUILD) -fstack-protector-all | 62 | $(BUILD) -fstack-protector-all |
62 | 63 | ||
63 | test-fortify-source.bin: | 64 | $(OUTPUT)test-fortify-source.bin: |
64 | $(BUILD) -O2 -D_FORTIFY_SOURCE=2 | 65 | $(BUILD) -O2 -D_FORTIFY_SOURCE=2 |
65 | 66 | ||
66 | test-bionic.bin: | 67 | $(OUTPUT)test-bionic.bin: |
67 | $(BUILD) | 68 | $(BUILD) |
68 | 69 | ||
69 | test-libelf.bin: | 70 | $(OUTPUT)test-libelf.bin: |
70 | $(BUILD) -lelf | 71 | $(BUILD) -lelf |
71 | 72 | ||
72 | test-glibc.bin: | 73 | $(OUTPUT)test-glibc.bin: |
73 | $(BUILD) | 74 | $(BUILD) |
74 | 75 | ||
75 | DWARFLIBS := -ldw | 76 | DWARFLIBS := -ldw |
@@ -77,37 +78,37 @@ ifeq ($(findstring -static,${LDFLAGS}),-static) | |||
77 | DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 | 78 | DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 |
78 | endif | 79 | endif |
79 | 80 | ||
80 | test-dwarf.bin: | 81 | $(OUTPUT)test-dwarf.bin: |
81 | $(BUILD) $(DWARFLIBS) | 82 | $(BUILD) $(DWARFLIBS) |
82 | 83 | ||
83 | test-libelf-mmap.bin: | 84 | $(OUTPUT)test-libelf-mmap.bin: |
84 | $(BUILD) -lelf | 85 | $(BUILD) -lelf |
85 | 86 | ||
86 | test-libelf-getphdrnum.bin: | 87 | $(OUTPUT)test-libelf-getphdrnum.bin: |
87 | $(BUILD) -lelf | 88 | $(BUILD) -lelf |
88 | 89 | ||
89 | test-libnuma.bin: | 90 | $(OUTPUT)test-libnuma.bin: |
90 | $(BUILD) -lnuma | 91 | $(BUILD) -lnuma |
91 | 92 | ||
92 | test-numa_num_possible_cpus.bin: | 93 | $(OUTPUT)test-numa_num_possible_cpus.bin: |
93 | $(BUILD) -lnuma | 94 | $(BUILD) -lnuma |
94 | 95 | ||
95 | test-libunwind.bin: | 96 | $(OUTPUT)test-libunwind.bin: |
96 | $(BUILD) -lelf | 97 | $(BUILD) -lelf |
97 | 98 | ||
98 | test-libunwind-debug-frame.bin: | 99 | $(OUTPUT)test-libunwind-debug-frame.bin: |
99 | $(BUILD) -lelf | 100 | $(BUILD) -lelf |
100 | 101 | ||
101 | test-libaudit.bin: | 102 | $(OUTPUT)test-libaudit.bin: |
102 | $(BUILD) -laudit | 103 | $(BUILD) -laudit |
103 | 104 | ||
104 | test-libslang.bin: | 105 | $(OUTPUT)test-libslang.bin: |
105 | $(BUILD) -I/usr/include/slang -lslang | 106 | $(BUILD) -I/usr/include/slang -lslang |
106 | 107 | ||
107 | test-gtk2.bin: | 108 | $(OUTPUT)test-gtk2.bin: |
108 | $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) | 109 | $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) |
109 | 110 | ||
110 | test-gtk2-infobar.bin: | 111 | $(OUTPUT)test-gtk2-infobar.bin: |
111 | $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) | 112 | $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) |
112 | 113 | ||
113 | grep-libs = $(filter -l%,$(1)) | 114 | grep-libs = $(filter -l%,$(1)) |
@@ -119,63 +120,63 @@ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) | |||
119 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` | 120 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` |
120 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) | 121 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) |
121 | 122 | ||
122 | test-libperl.bin: | 123 | $(OUTPUT)test-libperl.bin: |
123 | $(BUILD) $(FLAGS_PERL_EMBED) | 124 | $(BUILD) $(FLAGS_PERL_EMBED) |
124 | 125 | ||
125 | test-libpython.bin: | 126 | $(OUTPUT)test-libpython.bin: |
126 | $(BUILD) | 127 | $(BUILD) |
127 | 128 | ||
128 | test-libpython-version.bin: | 129 | $(OUTPUT)test-libpython-version.bin: |
129 | $(BUILD) | 130 | $(BUILD) |
130 | 131 | ||
131 | test-libbfd.bin: | 132 | $(OUTPUT)test-libbfd.bin: |
132 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl | 133 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl |
133 | 134 | ||
134 | test-liberty.bin: | 135 | $(OUTPUT)test-liberty.bin: |
135 | $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty | 136 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty |
136 | 137 | ||
137 | test-liberty-z.bin: | 138 | $(OUTPUT)test-liberty-z.bin: |
138 | $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz | 139 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz |
139 | 140 | ||
140 | test-cplus-demangle.bin: | 141 | $(OUTPUT)test-cplus-demangle.bin: |
141 | $(BUILD) -liberty | 142 | $(BUILD) -liberty |
142 | 143 | ||
143 | test-backtrace.bin: | 144 | $(OUTPUT)test-backtrace.bin: |
144 | $(BUILD) | 145 | $(BUILD) |
145 | 146 | ||
146 | test-timerfd.bin: | 147 | $(OUTPUT)test-timerfd.bin: |
147 | $(BUILD) | 148 | $(BUILD) |
148 | 149 | ||
149 | test-libdw-dwarf-unwind.bin: | 150 | $(OUTPUT)test-libdw-dwarf-unwind.bin: |
150 | $(BUILD) # -ldw provided by $(FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind) | 151 | $(BUILD) # -ldw provided by $(FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind) |
151 | 152 | ||
152 | test-libbabeltrace.bin: | 153 | $(OUTPUT)test-libbabeltrace.bin: |
153 | $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace) | 154 | $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace) |
154 | 155 | ||
155 | test-sync-compare-and-swap.bin: | 156 | $(OUTPUT)test-sync-compare-and-swap.bin: |
156 | $(BUILD) | 157 | $(BUILD) |
157 | 158 | ||
158 | test-compile-32.bin: | 159 | $(OUTPUT)test-compile-32.bin: |
159 | $(CC) -m32 -o $(OUTPUT)$@ test-compile.c | 160 | $(CC) -m32 -o $@ test-compile.c |
160 | 161 | ||
161 | test-compile-x32.bin: | 162 | $(OUTPUT)test-compile-x32.bin: |
162 | $(CC) -mx32 -o $(OUTPUT)$@ test-compile.c | 163 | $(CC) -mx32 -o $@ test-compile.c |
163 | 164 | ||
164 | test-zlib.bin: | 165 | $(OUTPUT)test-zlib.bin: |
165 | $(BUILD) -lz | 166 | $(BUILD) -lz |
166 | 167 | ||
167 | test-lzma.bin: | 168 | $(OUTPUT)test-lzma.bin: |
168 | $(BUILD) -llzma | 169 | $(BUILD) -llzma |
169 | 170 | ||
170 | test-get_cpuid.bin: | 171 | $(OUTPUT)test-get_cpuid.bin: |
171 | $(BUILD) | 172 | $(BUILD) |
172 | 173 | ||
173 | test-bpf.bin: | 174 | $(OUTPUT)test-bpf.bin: |
174 | $(BUILD) | 175 | $(BUILD) |
175 | 176 | ||
176 | -include *.d | 177 | -include $(OUTPUT)*.d |
177 | 178 | ||
178 | ############################### | 179 | ############################### |
179 | 180 | ||
180 | clean: | 181 | clean: |
181 | rm -f $(FILES) *.d $(FILES:.bin=.make.output) | 182 | rm -f $(FILES) $(OUTPUT)*.d $(FILES:.bin=.make.output) |
diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index 2e2f736c039c..e26223f1f287 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h | |||
@@ -8,4 +8,8 @@ void *memdup(const void *src, size_t len); | |||
8 | 8 | ||
9 | int strtobool(const char *s, bool *res); | 9 | int strtobool(const char *s, bool *res); |
10 | 10 | ||
11 | #ifndef __UCLIBC__ | ||
12 | extern size_t strlcpy(char *dest, const char *src, size_t size); | ||
13 | #endif | ||
14 | |||
11 | #endif /* _LINUX_STRING_H_ */ | 15 | #endif /* _LINUX_STRING_H_ */ |
diff --git a/tools/lib/string.c b/tools/lib/string.c index 065e54f42d8f..bd239bc1d557 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <string.h> | 16 | #include <string.h> |
17 | #include <errno.h> | 17 | #include <errno.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/compiler.h> | ||
19 | 20 | ||
20 | /** | 21 | /** |
21 | * memdup - duplicate region of memory | 22 | * memdup - duplicate region of memory |
@@ -60,3 +61,29 @@ int strtobool(const char *s, bool *res) | |||
60 | } | 61 | } |
61 | return 0; | 62 | return 0; |
62 | } | 63 | } |
64 | |||
65 | /** | ||
66 | * strlcpy - Copy a C-string into a sized buffer | ||
67 | * @dest: Where to copy the string to | ||
68 | * @src: Where to copy the string from | ||
69 | * @size: size of destination buffer | ||
70 | * | ||
71 | * Compatible with *BSD: the result is always a valid | ||
72 | * NUL-terminated string that fits in the buffer (unless, | ||
73 | * of course, the buffer size is zero). It does not pad | ||
74 | * out the result like strncpy() does. | ||
75 | * | ||
76 | * If libc has strlcpy() then that version will override this | ||
77 | * implementation: | ||
78 | */ | ||
79 | size_t __weak strlcpy(char *dest, const char *src, size_t size) | ||
80 | { | ||
81 | size_t ret = strlen(src); | ||
82 | |||
83 | if (size) { | ||
84 | size_t len = (ret >= size) ? size - 1 : ret; | ||
85 | memcpy(dest, src, len); | ||
86 | dest[len] = '\0'; | ||
87 | } | ||
88 | return ret; | ||
89 | } | ||
diff --git a/tools/lib/subcmd/Build b/tools/lib/subcmd/Build new file mode 100644 index 000000000000..ee31288788c1 --- /dev/null +++ b/tools/lib/subcmd/Build | |||
@@ -0,0 +1,7 @@ | |||
1 | libsubcmd-y += exec-cmd.o | ||
2 | libsubcmd-y += help.o | ||
3 | libsubcmd-y += pager.o | ||
4 | libsubcmd-y += parse-options.o | ||
5 | libsubcmd-y += run-command.o | ||
6 | libsubcmd-y += sigchain.o | ||
7 | libsubcmd-y += subcmd-config.o | ||
diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile new file mode 100644 index 000000000000..629cf8c14e68 --- /dev/null +++ b/tools/lib/subcmd/Makefile | |||
@@ -0,0 +1,48 @@ | |||
1 | include ../../scripts/Makefile.include | ||
2 | include ../../perf/config/utilities.mak # QUIET_CLEAN | ||
3 | |||
4 | ifeq ($(srctree),) | ||
5 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | ||
6 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
7 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
8 | #$(info Determined 'srctree' to be $(srctree)) | ||
9 | endif | ||
10 | |||
11 | CC = $(CROSS_COMPILE)gcc | ||
12 | AR = $(CROSS_COMPILE)ar | ||
13 | RM = rm -f | ||
14 | |||
15 | MAKEFLAGS += --no-print-directory | ||
16 | |||
17 | LIBFILE = $(OUTPUT)libsubcmd.a | ||
18 | |||
19 | CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) | ||
20 | CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC | ||
21 | CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE | ||
22 | |||
23 | CFLAGS += -I$(srctree)/tools/include/ | ||
24 | CFLAGS += -I$(srctree)/include/uapi | ||
25 | CFLAGS += -I$(srctree)/include | ||
26 | |||
27 | SUBCMD_IN := $(OUTPUT)libsubcmd-in.o | ||
28 | |||
29 | all: | ||
30 | |||
31 | export srctree OUTPUT CC LD CFLAGS V | ||
32 | include $(srctree)/tools/build/Makefile.include | ||
33 | |||
34 | all: fixdep $(LIBFILE) | ||
35 | |||
36 | $(SUBCMD_IN): FORCE | ||
37 | @$(MAKE) $(build)=libsubcmd | ||
38 | |||
39 | $(LIBFILE): $(SUBCMD_IN) | ||
40 | $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(SUBCMD_IN) | ||
41 | |||
42 | clean: | ||
43 | $(call QUIET_CLEAN, libsubcmd) $(RM) $(LIBFILE); \ | ||
44 | find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) | ||
45 | |||
46 | FORCE: | ||
47 | |||
48 | .PHONY: clean FORCE | ||
diff --git a/tools/lib/subcmd/exec-cmd.c b/tools/lib/subcmd/exec-cmd.c new file mode 100644 index 000000000000..1ae833af1a4a --- /dev/null +++ b/tools/lib/subcmd/exec-cmd.c | |||
@@ -0,0 +1,209 @@ | |||
1 | #include <linux/compiler.h> | ||
2 | #include <linux/string.h> | ||
3 | #include <sys/types.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include <unistd.h> | ||
6 | #include <string.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <stdio.h> | ||
9 | #include "subcmd-util.h" | ||
10 | #include "exec-cmd.h" | ||
11 | #include "subcmd-config.h" | ||
12 | |||
13 | #define MAX_ARGS 32 | ||
14 | #define PATH_MAX 4096 | ||
15 | |||
16 | static const char *argv_exec_path; | ||
17 | static const char *argv0_path; | ||
18 | |||
19 | void exec_cmd_init(const char *exec_name, const char *prefix, | ||
20 | const char *exec_path, const char *exec_path_env) | ||
21 | { | ||
22 | subcmd_config.exec_name = exec_name; | ||
23 | subcmd_config.prefix = prefix; | ||
24 | subcmd_config.exec_path = exec_path; | ||
25 | subcmd_config.exec_path_env = exec_path_env; | ||
26 | } | ||
27 | |||
28 | #define is_dir_sep(c) ((c) == '/') | ||
29 | |||
30 | static int is_absolute_path(const char *path) | ||
31 | { | ||
32 | return path[0] == '/'; | ||
33 | } | ||
34 | |||
35 | static const char *get_pwd_cwd(void) | ||
36 | { | ||
37 | static char cwd[PATH_MAX + 1]; | ||
38 | char *pwd; | ||
39 | struct stat cwd_stat, pwd_stat; | ||
40 | if (getcwd(cwd, PATH_MAX) == NULL) | ||
41 | return NULL; | ||
42 | pwd = getenv("PWD"); | ||
43 | if (pwd && strcmp(pwd, cwd)) { | ||
44 | stat(cwd, &cwd_stat); | ||
45 | if (!stat(pwd, &pwd_stat) && | ||
46 | pwd_stat.st_dev == cwd_stat.st_dev && | ||
47 | pwd_stat.st_ino == cwd_stat.st_ino) { | ||
48 | strlcpy(cwd, pwd, PATH_MAX); | ||
49 | } | ||
50 | } | ||
51 | return cwd; | ||
52 | } | ||
53 | |||
54 | static const char *make_nonrelative_path(const char *path) | ||
55 | { | ||
56 | static char buf[PATH_MAX + 1]; | ||
57 | |||
58 | if (is_absolute_path(path)) { | ||
59 | if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) | ||
60 | die("Too long path: %.*s", 60, path); | ||
61 | } else { | ||
62 | const char *cwd = get_pwd_cwd(); | ||
63 | if (!cwd) | ||
64 | die("Cannot determine the current working directory"); | ||
65 | if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX) | ||
66 | die("Too long path: %.*s", 60, path); | ||
67 | } | ||
68 | return buf; | ||
69 | } | ||
70 | |||
71 | char *system_path(const char *path) | ||
72 | { | ||
73 | char *buf = NULL; | ||
74 | |||
75 | if (is_absolute_path(path)) | ||
76 | return strdup(path); | ||
77 | |||
78 | astrcatf(&buf, "%s/%s", subcmd_config.prefix, path); | ||
79 | |||
80 | return buf; | ||
81 | } | ||
82 | |||
83 | const char *extract_argv0_path(const char *argv0) | ||
84 | { | ||
85 | const char *slash; | ||
86 | |||
87 | if (!argv0 || !*argv0) | ||
88 | return NULL; | ||
89 | slash = argv0 + strlen(argv0); | ||
90 | |||
91 | while (argv0 <= slash && !is_dir_sep(*slash)) | ||
92 | slash--; | ||
93 | |||
94 | if (slash >= argv0) { | ||
95 | argv0_path = strndup(argv0, slash - argv0); | ||
96 | return argv0_path ? slash + 1 : NULL; | ||
97 | } | ||
98 | |||
99 | return argv0; | ||
100 | } | ||
101 | |||
102 | void set_argv_exec_path(const char *exec_path) | ||
103 | { | ||
104 | argv_exec_path = exec_path; | ||
105 | /* | ||
106 | * Propagate this setting to external programs. | ||
107 | */ | ||
108 | setenv(subcmd_config.exec_path_env, exec_path, 1); | ||
109 | } | ||
110 | |||
111 | |||
112 | /* Returns the highest-priority location to look for subprograms. */ | ||
113 | char *get_argv_exec_path(void) | ||
114 | { | ||
115 | char *env; | ||
116 | |||
117 | if (argv_exec_path) | ||
118 | return strdup(argv_exec_path); | ||
119 | |||
120 | env = getenv(subcmd_config.exec_path_env); | ||
121 | if (env && *env) | ||
122 | return strdup(env); | ||
123 | |||
124 | return system_path(subcmd_config.exec_path); | ||
125 | } | ||
126 | |||
127 | static void add_path(char **out, const char *path) | ||
128 | { | ||
129 | if (path && *path) { | ||
130 | if (is_absolute_path(path)) | ||
131 | astrcat(out, path); | ||
132 | else | ||
133 | astrcat(out, make_nonrelative_path(path)); | ||
134 | |||
135 | astrcat(out, ":"); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | void setup_path(void) | ||
140 | { | ||
141 | const char *old_path = getenv("PATH"); | ||
142 | char *new_path = NULL; | ||
143 | char *tmp = get_argv_exec_path(); | ||
144 | |||
145 | add_path(&new_path, tmp); | ||
146 | add_path(&new_path, argv0_path); | ||
147 | free(tmp); | ||
148 | |||
149 | if (old_path) | ||
150 | astrcat(&new_path, old_path); | ||
151 | else | ||
152 | astrcat(&new_path, "/usr/local/bin:/usr/bin:/bin"); | ||
153 | |||
154 | setenv("PATH", new_path, 1); | ||
155 | |||
156 | free(new_path); | ||
157 | } | ||
158 | |||
159 | static const char **prepare_exec_cmd(const char **argv) | ||
160 | { | ||
161 | int argc; | ||
162 | const char **nargv; | ||
163 | |||
164 | for (argc = 0; argv[argc]; argc++) | ||
165 | ; /* just counting */ | ||
166 | nargv = malloc(sizeof(*nargv) * (argc + 2)); | ||
167 | |||
168 | nargv[0] = subcmd_config.exec_name; | ||
169 | for (argc = 0; argv[argc]; argc++) | ||
170 | nargv[argc + 1] = argv[argc]; | ||
171 | nargv[argc + 1] = NULL; | ||
172 | return nargv; | ||
173 | } | ||
174 | |||
175 | int execv_cmd(const char **argv) { | ||
176 | const char **nargv = prepare_exec_cmd(argv); | ||
177 | |||
178 | /* execvp() can only ever return if it fails */ | ||
179 | execvp(subcmd_config.exec_name, (char **)nargv); | ||
180 | |||
181 | free(nargv); | ||
182 | return -1; | ||
183 | } | ||
184 | |||
185 | |||
186 | int execl_cmd(const char *cmd,...) | ||
187 | { | ||
188 | int argc; | ||
189 | const char *argv[MAX_ARGS + 1]; | ||
190 | const char *arg; | ||
191 | va_list param; | ||
192 | |||
193 | va_start(param, cmd); | ||
194 | argv[0] = cmd; | ||
195 | argc = 1; | ||
196 | while (argc < MAX_ARGS) { | ||
197 | arg = argv[argc++] = va_arg(param, char *); | ||
198 | if (!arg) | ||
199 | break; | ||
200 | } | ||
201 | va_end(param); | ||
202 | if (MAX_ARGS <= argc) { | ||
203 | fprintf(stderr, " Error: too many args to run %s\n", cmd); | ||
204 | return -1; | ||
205 | } | ||
206 | |||
207 | argv[argc] = NULL; | ||
208 | return execv_cmd(argv); | ||
209 | } | ||
diff --git a/tools/lib/subcmd/exec-cmd.h b/tools/lib/subcmd/exec-cmd.h new file mode 100644 index 000000000000..5d08bda31d90 --- /dev/null +++ b/tools/lib/subcmd/exec-cmd.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef __SUBCMD_EXEC_CMD_H | ||
2 | #define __SUBCMD_EXEC_CMD_H | ||
3 | |||
4 | extern void exec_cmd_init(const char *exec_name, const char *prefix, | ||
5 | const char *exec_path, const char *exec_path_env); | ||
6 | |||
7 | extern void set_argv_exec_path(const char *exec_path); | ||
8 | extern const char *extract_argv0_path(const char *path); | ||
9 | extern void setup_path(void); | ||
10 | extern int execv_cmd(const char **argv); /* NULL terminated */ | ||
11 | extern int execl_cmd(const char *cmd, ...); | ||
12 | /* get_argv_exec_path and system_path return malloc'd string, caller must free it */ | ||
13 | extern char *get_argv_exec_path(void); | ||
14 | extern char *system_path(const char *path); | ||
15 | |||
16 | #endif /* __SUBCMD_EXEC_CMD_H */ | ||
diff --git a/tools/perf/util/help.c b/tools/lib/subcmd/help.c index 929c93f2c333..e228c3cb3716 100644 --- a/tools/perf/util/help.c +++ b/tools/lib/subcmd/help.c | |||
@@ -1,9 +1,15 @@ | |||
1 | #include "cache.h" | 1 | #include <stdio.h> |
2 | #include "../builtin.h" | 2 | #include <stdlib.h> |
3 | #include "exec_cmd.h" | 3 | #include <string.h> |
4 | #include "levenshtein.h" | ||
5 | #include "help.h" | ||
6 | #include <termios.h> | 4 | #include <termios.h> |
5 | #include <sys/ioctl.h> | ||
6 | #include <sys/types.h> | ||
7 | #include <sys/stat.h> | ||
8 | #include <unistd.h> | ||
9 | #include <dirent.h> | ||
10 | #include "subcmd-util.h" | ||
11 | #include "help.h" | ||
12 | #include "exec-cmd.h" | ||
7 | 13 | ||
8 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) | 14 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) |
9 | { | 15 | { |
@@ -17,7 +23,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) | |||
17 | cmds->names[cmds->cnt++] = ent; | 23 | cmds->names[cmds->cnt++] = ent; |
18 | } | 24 | } |
19 | 25 | ||
20 | static void clean_cmdnames(struct cmdnames *cmds) | 26 | void clean_cmdnames(struct cmdnames *cmds) |
21 | { | 27 | { |
22 | unsigned int i; | 28 | unsigned int i; |
23 | 29 | ||
@@ -28,14 +34,14 @@ static void clean_cmdnames(struct cmdnames *cmds) | |||
28 | cmds->alloc = 0; | 34 | cmds->alloc = 0; |
29 | } | 35 | } |
30 | 36 | ||
31 | static int cmdname_compare(const void *a_, const void *b_) | 37 | int cmdname_compare(const void *a_, const void *b_) |
32 | { | 38 | { |
33 | struct cmdname *a = *(struct cmdname **)a_; | 39 | struct cmdname *a = *(struct cmdname **)a_; |
34 | struct cmdname *b = *(struct cmdname **)b_; | 40 | struct cmdname *b = *(struct cmdname **)b_; |
35 | return strcmp(a->name, b->name); | 41 | return strcmp(a->name, b->name); |
36 | } | 42 | } |
37 | 43 | ||
38 | static void uniq(struct cmdnames *cmds) | 44 | void uniq(struct cmdnames *cmds) |
39 | { | 45 | { |
40 | unsigned int i, j; | 46 | unsigned int i, j; |
41 | 47 | ||
@@ -71,6 +77,28 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) | |||
71 | cmds->cnt = cj; | 77 | cmds->cnt = cj; |
72 | } | 78 | } |
73 | 79 | ||
80 | static void get_term_dimensions(struct winsize *ws) | ||
81 | { | ||
82 | char *s = getenv("LINES"); | ||
83 | |||
84 | if (s != NULL) { | ||
85 | ws->ws_row = atoi(s); | ||
86 | s = getenv("COLUMNS"); | ||
87 | if (s != NULL) { | ||
88 | ws->ws_col = atoi(s); | ||
89 | if (ws->ws_row && ws->ws_col) | ||
90 | return; | ||
91 | } | ||
92 | } | ||
93 | #ifdef TIOCGWINSZ | ||
94 | if (ioctl(1, TIOCGWINSZ, ws) == 0 && | ||
95 | ws->ws_row && ws->ws_col) | ||
96 | return; | ||
97 | #endif | ||
98 | ws->ws_row = 25; | ||
99 | ws->ws_col = 80; | ||
100 | } | ||
101 | |||
74 | static void pretty_print_string_list(struct cmdnames *cmds, int longest) | 102 | static void pretty_print_string_list(struct cmdnames *cmds, int longest) |
75 | { | 103 | { |
76 | int cols = 1, rows; | 104 | int cols = 1, rows; |
@@ -114,6 +142,14 @@ static int is_executable(const char *name) | |||
114 | return st.st_mode & S_IXUSR; | 142 | return st.st_mode & S_IXUSR; |
115 | } | 143 | } |
116 | 144 | ||
145 | static int has_extension(const char *filename, const char *ext) | ||
146 | { | ||
147 | size_t len = strlen(filename); | ||
148 | size_t extlen = strlen(ext); | ||
149 | |||
150 | return len > extlen && !memcmp(filename + len - extlen, ext, extlen); | ||
151 | } | ||
152 | |||
117 | static void list_commands_in_dir(struct cmdnames *cmds, | 153 | static void list_commands_in_dir(struct cmdnames *cmds, |
118 | const char *path, | 154 | const char *path, |
119 | const char *prefix) | 155 | const char *prefix) |
@@ -121,8 +157,7 @@ static void list_commands_in_dir(struct cmdnames *cmds, | |||
121 | int prefix_len; | 157 | int prefix_len; |
122 | DIR *dir = opendir(path); | 158 | DIR *dir = opendir(path); |
123 | struct dirent *de; | 159 | struct dirent *de; |
124 | struct strbuf buf = STRBUF_INIT; | 160 | char *buf = NULL; |
125 | int len; | ||
126 | 161 | ||
127 | if (!dir) | 162 | if (!dir) |
128 | return; | 163 | return; |
@@ -130,8 +165,7 @@ static void list_commands_in_dir(struct cmdnames *cmds, | |||
130 | prefix = "perf-"; | 165 | prefix = "perf-"; |
131 | prefix_len = strlen(prefix); | 166 | prefix_len = strlen(prefix); |
132 | 167 | ||
133 | strbuf_addf(&buf, "%s/", path); | 168 | astrcatf(&buf, "%s/", path); |
134 | len = buf.len; | ||
135 | 169 | ||
136 | while ((de = readdir(dir)) != NULL) { | 170 | while ((de = readdir(dir)) != NULL) { |
137 | int entlen; | 171 | int entlen; |
@@ -139,9 +173,8 @@ static void list_commands_in_dir(struct cmdnames *cmds, | |||
139 | if (prefixcmp(de->d_name, prefix)) | 173 | if (prefixcmp(de->d_name, prefix)) |
140 | continue; | 174 | continue; |
141 | 175 | ||
142 | strbuf_setlen(&buf, len); | 176 | astrcat(&buf, de->d_name); |
143 | strbuf_addstr(&buf, de->d_name); | 177 | if (!is_executable(buf)) |
144 | if (!is_executable(buf.buf)) | ||
145 | continue; | 178 | continue; |
146 | 179 | ||
147 | entlen = strlen(de->d_name) - prefix_len; | 180 | entlen = strlen(de->d_name) - prefix_len; |
@@ -151,7 +184,7 @@ static void list_commands_in_dir(struct cmdnames *cmds, | |||
151 | add_cmdname(cmds, de->d_name + prefix_len, entlen); | 184 | add_cmdname(cmds, de->d_name + prefix_len, entlen); |
152 | } | 185 | } |
153 | closedir(dir); | 186 | closedir(dir); |
154 | strbuf_release(&buf); | 187 | free(buf); |
155 | } | 188 | } |
156 | 189 | ||
157 | void load_command_list(const char *prefix, | 190 | void load_command_list(const char *prefix, |
@@ -159,7 +192,7 @@ void load_command_list(const char *prefix, | |||
159 | struct cmdnames *other_cmds) | 192 | struct cmdnames *other_cmds) |
160 | { | 193 | { |
161 | const char *env_path = getenv("PATH"); | 194 | const char *env_path = getenv("PATH"); |
162 | char *exec_path = perf_exec_path(); | 195 | char *exec_path = get_argv_exec_path(); |
163 | 196 | ||
164 | if (exec_path) { | 197 | if (exec_path) { |
165 | list_commands_in_dir(main_cmds, exec_path, prefix); | 198 | list_commands_in_dir(main_cmds, exec_path, prefix); |
@@ -172,7 +205,7 @@ void load_command_list(const char *prefix, | |||
172 | char *paths, *path, *colon; | 205 | char *paths, *path, *colon; |
173 | path = paths = strdup(env_path); | 206 | path = paths = strdup(env_path); |
174 | while (1) { | 207 | while (1) { |
175 | if ((colon = strchr(path, PATH_SEP))) | 208 | if ((colon = strchr(path, ':'))) |
176 | *colon = 0; | 209 | *colon = 0; |
177 | if (!exec_path || strcmp(path, exec_path)) | 210 | if (!exec_path || strcmp(path, exec_path)) |
178 | list_commands_in_dir(other_cmds, path, prefix); | 211 | list_commands_in_dir(other_cmds, path, prefix); |
@@ -204,7 +237,7 @@ void list_commands(const char *title, struct cmdnames *main_cmds, | |||
204 | longest = other_cmds->names[i]->len; | 237 | longest = other_cmds->names[i]->len; |
205 | 238 | ||
206 | if (main_cmds->cnt) { | 239 | if (main_cmds->cnt) { |
207 | char *exec_path = perf_exec_path(); | 240 | char *exec_path = get_argv_exec_path(); |
208 | printf("available %s in '%s'\n", title, exec_path); | 241 | printf("available %s in '%s'\n", title, exec_path); |
209 | printf("----------------"); | 242 | printf("----------------"); |
210 | mput_char('-', strlen(title) + strlen(exec_path)); | 243 | mput_char('-', strlen(title) + strlen(exec_path)); |
@@ -233,102 +266,3 @@ int is_in_cmdlist(struct cmdnames *c, const char *s) | |||
233 | return 1; | 266 | return 1; |
234 | return 0; | 267 | return 0; |
235 | } | 268 | } |
236 | |||
237 | static int autocorrect; | ||
238 | static struct cmdnames aliases; | ||
239 | |||
240 | static int perf_unknown_cmd_config(const char *var, const char *value, void *cb) | ||
241 | { | ||
242 | if (!strcmp(var, "help.autocorrect")) | ||
243 | autocorrect = perf_config_int(var,value); | ||
244 | /* Also use aliases for command lookup */ | ||
245 | if (!prefixcmp(var, "alias.")) | ||
246 | add_cmdname(&aliases, var + 6, strlen(var + 6)); | ||
247 | |||
248 | return perf_default_config(var, value, cb); | ||
249 | } | ||
250 | |||
251 | static int levenshtein_compare(const void *p1, const void *p2) | ||
252 | { | ||
253 | const struct cmdname *const *c1 = p1, *const *c2 = p2; | ||
254 | const char *s1 = (*c1)->name, *s2 = (*c2)->name; | ||
255 | int l1 = (*c1)->len; | ||
256 | int l2 = (*c2)->len; | ||
257 | return l1 != l2 ? l1 - l2 : strcmp(s1, s2); | ||
258 | } | ||
259 | |||
260 | static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) | ||
261 | { | ||
262 | unsigned int i; | ||
263 | |||
264 | ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); | ||
265 | |||
266 | for (i = 0; i < old->cnt; i++) | ||
267 | cmds->names[cmds->cnt++] = old->names[i]; | ||
268 | zfree(&old->names); | ||
269 | old->cnt = 0; | ||
270 | } | ||
271 | |||
272 | const char *help_unknown_cmd(const char *cmd) | ||
273 | { | ||
274 | unsigned int i, n = 0, best_similarity = 0; | ||
275 | struct cmdnames main_cmds, other_cmds; | ||
276 | |||
277 | memset(&main_cmds, 0, sizeof(main_cmds)); | ||
278 | memset(&other_cmds, 0, sizeof(main_cmds)); | ||
279 | memset(&aliases, 0, sizeof(aliases)); | ||
280 | |||
281 | perf_config(perf_unknown_cmd_config, NULL); | ||
282 | |||
283 | load_command_list("perf-", &main_cmds, &other_cmds); | ||
284 | |||
285 | add_cmd_list(&main_cmds, &aliases); | ||
286 | add_cmd_list(&main_cmds, &other_cmds); | ||
287 | qsort(main_cmds.names, main_cmds.cnt, | ||
288 | sizeof(main_cmds.names), cmdname_compare); | ||
289 | uniq(&main_cmds); | ||
290 | |||
291 | if (main_cmds.cnt) { | ||
292 | /* This reuses cmdname->len for similarity index */ | ||
293 | for (i = 0; i < main_cmds.cnt; ++i) | ||
294 | main_cmds.names[i]->len = | ||
295 | levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4); | ||
296 | |||
297 | qsort(main_cmds.names, main_cmds.cnt, | ||
298 | sizeof(*main_cmds.names), levenshtein_compare); | ||
299 | |||
300 | best_similarity = main_cmds.names[0]->len; | ||
301 | n = 1; | ||
302 | while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len) | ||
303 | ++n; | ||
304 | } | ||
305 | |||
306 | if (autocorrect && n == 1) { | ||
307 | const char *assumed = main_cmds.names[0]->name; | ||
308 | |||
309 | main_cmds.names[0] = NULL; | ||
310 | clean_cmdnames(&main_cmds); | ||
311 | fprintf(stderr, "WARNING: You called a perf program named '%s', " | ||
312 | "which does not exist.\n" | ||
313 | "Continuing under the assumption that you meant '%s'\n", | ||
314 | cmd, assumed); | ||
315 | if (autocorrect > 0) { | ||
316 | fprintf(stderr, "in %0.1f seconds automatically...\n", | ||
317 | (float)autocorrect/10.0); | ||
318 | poll(NULL, 0, autocorrect * 100); | ||
319 | } | ||
320 | return assumed; | ||
321 | } | ||
322 | |||
323 | fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd); | ||
324 | |||
325 | if (main_cmds.cnt && best_similarity < 6) { | ||
326 | fprintf(stderr, "\nDid you mean %s?\n", | ||
327 | n < 2 ? "this": "one of these"); | ||
328 | |||
329 | for (i = 0; i < n; i++) | ||
330 | fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); | ||
331 | } | ||
332 | |||
333 | exit(1); | ||
334 | } | ||
diff --git a/tools/perf/util/help.h b/tools/lib/subcmd/help.h index 7f5c6dedd714..e145a020780c 100644 --- a/tools/perf/util/help.h +++ b/tools/lib/subcmd/help.h | |||
@@ -1,12 +1,14 @@ | |||
1 | #ifndef __PERF_HELP_H | 1 | #ifndef __SUBCMD_HELP_H |
2 | #define __PERF_HELP_H | 2 | #define __SUBCMD_HELP_H |
3 | |||
4 | #include <sys/types.h> | ||
3 | 5 | ||
4 | struct cmdnames { | 6 | struct cmdnames { |
5 | size_t alloc; | 7 | size_t alloc; |
6 | size_t cnt; | 8 | size_t cnt; |
7 | struct cmdname { | 9 | struct cmdname { |
8 | size_t len; /* also used for similarity index in help.c */ | 10 | size_t len; /* also used for similarity index in help.c */ |
9 | char name[FLEX_ARRAY]; | 11 | char name[]; |
10 | } **names; | 12 | } **names; |
11 | }; | 13 | }; |
12 | 14 | ||
@@ -20,10 +22,13 @@ void load_command_list(const char *prefix, | |||
20 | struct cmdnames *main_cmds, | 22 | struct cmdnames *main_cmds, |
21 | struct cmdnames *other_cmds); | 23 | struct cmdnames *other_cmds); |
22 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len); | 24 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len); |
25 | void clean_cmdnames(struct cmdnames *cmds); | ||
26 | int cmdname_compare(const void *a, const void *b); | ||
27 | void uniq(struct cmdnames *cmds); | ||
23 | /* Here we require that excludes is a sorted list. */ | 28 | /* Here we require that excludes is a sorted list. */ |
24 | void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); | 29 | void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); |
25 | int is_in_cmdlist(struct cmdnames *c, const char *s); | 30 | int is_in_cmdlist(struct cmdnames *c, const char *s); |
26 | void list_commands(const char *title, struct cmdnames *main_cmds, | 31 | void list_commands(const char *title, struct cmdnames *main_cmds, |
27 | struct cmdnames *other_cmds); | 32 | struct cmdnames *other_cmds); |
28 | 33 | ||
29 | #endif /* __PERF_HELP_H */ | 34 | #endif /* __SUBCMD_HELP_H */ |
diff --git a/tools/perf/util/pager.c b/tools/lib/subcmd/pager.c index 53ef006a951c..d50f3b58606b 100644 --- a/tools/perf/util/pager.c +++ b/tools/lib/subcmd/pager.c | |||
@@ -1,6 +1,12 @@ | |||
1 | #include "cache.h" | 1 | #include <sys/select.h> |
2 | #include <stdlib.h> | ||
3 | #include <stdio.h> | ||
4 | #include <string.h> | ||
5 | #include <signal.h> | ||
6 | #include "pager.h" | ||
2 | #include "run-command.h" | 7 | #include "run-command.h" |
3 | #include "sigchain.h" | 8 | #include "sigchain.h" |
9 | #include "subcmd-config.h" | ||
4 | 10 | ||
5 | /* | 11 | /* |
6 | * This is split up from the rest of git so that we can do | 12 | * This is split up from the rest of git so that we can do |
@@ -9,6 +15,11 @@ | |||
9 | 15 | ||
10 | static int spawned_pager; | 16 | static int spawned_pager; |
11 | 17 | ||
18 | void pager_init(const char *pager_env) | ||
19 | { | ||
20 | subcmd_config.pager_env = pager_env; | ||
21 | } | ||
22 | |||
12 | static void pager_preexec(void) | 23 | static void pager_preexec(void) |
13 | { | 24 | { |
14 | /* | 25 | /* |
@@ -46,7 +57,7 @@ static void wait_for_pager_signal(int signo) | |||
46 | 57 | ||
47 | void setup_pager(void) | 58 | void setup_pager(void) |
48 | { | 59 | { |
49 | const char *pager = getenv("PERF_PAGER"); | 60 | const char *pager = getenv(subcmd_config.pager_env); |
50 | 61 | ||
51 | if (!isatty(1)) | 62 | if (!isatty(1)) |
52 | return; | 63 | return; |
@@ -85,11 +96,5 @@ void setup_pager(void) | |||
85 | 96 | ||
86 | int pager_in_use(void) | 97 | int pager_in_use(void) |
87 | { | 98 | { |
88 | const char *env; | 99 | return spawned_pager; |
89 | |||
90 | if (spawned_pager) | ||
91 | return 1; | ||
92 | |||
93 | env = getenv("PERF_PAGER_IN_USE"); | ||
94 | return env ? perf_config_bool("PERF_PAGER_IN_USE", env) : 0; | ||
95 | } | 100 | } |
diff --git a/tools/lib/subcmd/pager.h b/tools/lib/subcmd/pager.h new file mode 100644 index 000000000000..8b83714ecf73 --- /dev/null +++ b/tools/lib/subcmd/pager.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef __SUBCMD_PAGER_H | ||
2 | #define __SUBCMD_PAGER_H | ||
3 | |||
4 | extern void pager_init(const char *pager_env); | ||
5 | |||
6 | extern void setup_pager(void); | ||
7 | extern int pager_in_use(void); | ||
8 | |||
9 | #endif /* __SUBCMD_PAGER_H */ | ||
diff --git a/tools/perf/util/parse-options.c b/tools/lib/subcmd/parse-options.c index de3290b47db1..981bb4481fd5 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/lib/subcmd/parse-options.c | |||
@@ -1,37 +1,66 @@ | |||
1 | #include "util.h" | 1 | #include <linux/compiler.h> |
2 | #include <linux/types.h> | ||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <stdint.h> | ||
6 | #include <string.h> | ||
7 | #include <ctype.h> | ||
8 | #include "subcmd-util.h" | ||
2 | #include "parse-options.h" | 9 | #include "parse-options.h" |
3 | #include "cache.h" | 10 | #include "subcmd-config.h" |
4 | #include "header.h" | 11 | #include "pager.h" |
5 | #include <linux/string.h> | ||
6 | 12 | ||
7 | #define OPT_SHORT 1 | 13 | #define OPT_SHORT 1 |
8 | #define OPT_UNSET 2 | 14 | #define OPT_UNSET 2 |
9 | 15 | ||
10 | static struct strbuf error_buf = STRBUF_INIT; | 16 | char *error_buf; |
11 | 17 | ||
12 | static int opterror(const struct option *opt, const char *reason, int flags) | 18 | static int opterror(const struct option *opt, const char *reason, int flags) |
13 | { | 19 | { |
14 | if (flags & OPT_SHORT) | 20 | if (flags & OPT_SHORT) |
15 | return error("switch `%c' %s", opt->short_name, reason); | 21 | fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason); |
16 | if (flags & OPT_UNSET) | 22 | else if (flags & OPT_UNSET) |
17 | return error("option `no-%s' %s", opt->long_name, reason); | 23 | fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason); |
18 | return error("option `%s' %s", opt->long_name, reason); | 24 | else |
25 | fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason); | ||
26 | |||
27 | return -1; | ||
28 | } | ||
29 | |||
30 | static const char *skip_prefix(const char *str, const char *prefix) | ||
31 | { | ||
32 | size_t len = strlen(prefix); | ||
33 | return strncmp(str, prefix, len) ? NULL : str + len; | ||
34 | } | ||
35 | |||
36 | static void optwarning(const struct option *opt, const char *reason, int flags) | ||
37 | { | ||
38 | if (flags & OPT_SHORT) | ||
39 | fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason); | ||
40 | else if (flags & OPT_UNSET) | ||
41 | fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason); | ||
42 | else | ||
43 | fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason); | ||
19 | } | 44 | } |
20 | 45 | ||
21 | static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, | 46 | static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, |
22 | int flags, const char **arg) | 47 | int flags, const char **arg) |
23 | { | 48 | { |
49 | const char *res; | ||
50 | |||
24 | if (p->opt) { | 51 | if (p->opt) { |
25 | *arg = p->opt; | 52 | res = p->opt; |
26 | p->opt = NULL; | 53 | p->opt = NULL; |
27 | } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 || | 54 | } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 || |
28 | **(p->argv + 1) == '-')) { | 55 | **(p->argv + 1) == '-')) { |
29 | *arg = (const char *)opt->defval; | 56 | res = (const char *)opt->defval; |
30 | } else if (p->argc > 1) { | 57 | } else if (p->argc > 1) { |
31 | p->argc--; | 58 | p->argc--; |
32 | *arg = *++p->argv; | 59 | res = *++p->argv; |
33 | } else | 60 | } else |
34 | return opterror(opt, "requires a value", flags); | 61 | return opterror(opt, "requires a value", flags); |
62 | if (arg) | ||
63 | *arg = res; | ||
35 | return 0; | 64 | return 0; |
36 | } | 65 | } |
37 | 66 | ||
@@ -55,11 +84,11 @@ static int get_value(struct parse_opt_ctx_t *p, | |||
55 | 84 | ||
56 | if (((flags & OPT_SHORT) && p->excl_opt->short_name) || | 85 | if (((flags & OPT_SHORT) && p->excl_opt->short_name) || |
57 | p->excl_opt->long_name == NULL) { | 86 | p->excl_opt->long_name == NULL) { |
58 | scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'", | 87 | snprintf(msg, sizeof(msg), "cannot be used with switch `%c'", |
59 | p->excl_opt->short_name); | 88 | p->excl_opt->short_name); |
60 | } else { | 89 | } else { |
61 | scnprintf(msg, sizeof(msg), "cannot be used with %s", | 90 | snprintf(msg, sizeof(msg), "cannot be used with %s", |
62 | p->excl_opt->long_name); | 91 | p->excl_opt->long_name); |
63 | } | 92 | } |
64 | opterror(opt, msg, flags); | 93 | opterror(opt, msg, flags); |
65 | return -3; | 94 | return -3; |
@@ -91,6 +120,64 @@ static int get_value(struct parse_opt_ctx_t *p, | |||
91 | } | 120 | } |
92 | } | 121 | } |
93 | 122 | ||
123 | if (opt->flags & PARSE_OPT_NOBUILD) { | ||
124 | char reason[128]; | ||
125 | bool noarg = false; | ||
126 | |||
127 | err = snprintf(reason, sizeof(reason), | ||
128 | opt->flags & PARSE_OPT_CANSKIP ? | ||
129 | "is being ignored because %s " : | ||
130 | "is not available because %s", | ||
131 | opt->build_opt); | ||
132 | reason[sizeof(reason) - 1] = '\0'; | ||
133 | |||
134 | if (err < 0) | ||
135 | strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ? | ||
136 | "is being ignored" : | ||
137 | "is not available", | ||
138 | sizeof(reason)); | ||
139 | |||
140 | if (!(opt->flags & PARSE_OPT_CANSKIP)) | ||
141 | return opterror(opt, reason, flags); | ||
142 | |||
143 | err = 0; | ||
144 | if (unset) | ||
145 | noarg = true; | ||
146 | if (opt->flags & PARSE_OPT_NOARG) | ||
147 | noarg = true; | ||
148 | if (opt->flags & PARSE_OPT_OPTARG && !p->opt) | ||
149 | noarg = true; | ||
150 | |||
151 | switch (opt->type) { | ||
152 | case OPTION_BOOLEAN: | ||
153 | case OPTION_INCR: | ||
154 | case OPTION_BIT: | ||
155 | case OPTION_SET_UINT: | ||
156 | case OPTION_SET_PTR: | ||
157 | case OPTION_END: | ||
158 | case OPTION_ARGUMENT: | ||
159 | case OPTION_GROUP: | ||
160 | noarg = true; | ||
161 | break; | ||
162 | case OPTION_CALLBACK: | ||
163 | case OPTION_STRING: | ||
164 | case OPTION_INTEGER: | ||
165 | case OPTION_UINTEGER: | ||
166 | case OPTION_LONG: | ||
167 | case OPTION_U64: | ||
168 | default: | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | if (!noarg) | ||
173 | err = get_arg(p, opt, flags, NULL); | ||
174 | if (err) | ||
175 | return err; | ||
176 | |||
177 | optwarning(opt, reason, flags); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
94 | switch (opt->type) { | 181 | switch (opt->type) { |
95 | case OPTION_BIT: | 182 | case OPTION_BIT: |
96 | if (unset) | 183 | if (unset) |
@@ -327,14 +414,16 @@ match: | |||
327 | return get_value(p, options, flags); | 414 | return get_value(p, options, flags); |
328 | } | 415 | } |
329 | 416 | ||
330 | if (ambiguous_option) | 417 | if (ambiguous_option) { |
331 | return error("Ambiguous option: %s " | 418 | fprintf(stderr, |
332 | "(could be --%s%s or --%s%s)", | 419 | " Error: Ambiguous option: %s (could be --%s%s or --%s%s)", |
333 | arg, | 420 | arg, |
334 | (ambiguous_flags & OPT_UNSET) ? "no-" : "", | 421 | (ambiguous_flags & OPT_UNSET) ? "no-" : "", |
335 | ambiguous_option->long_name, | 422 | ambiguous_option->long_name, |
336 | (abbrev_flags & OPT_UNSET) ? "no-" : "", | 423 | (abbrev_flags & OPT_UNSET) ? "no-" : "", |
337 | abbrev_option->long_name); | 424 | abbrev_option->long_name); |
425 | return -1; | ||
426 | } | ||
338 | if (abbrev_option) | 427 | if (abbrev_option) |
339 | return get_value(p, abbrev_option, abbrev_flags); | 428 | return get_value(p, abbrev_option, abbrev_flags); |
340 | return -2; | 429 | return -2; |
@@ -346,7 +435,7 @@ static void check_typos(const char *arg, const struct option *options) | |||
346 | return; | 435 | return; |
347 | 436 | ||
348 | if (!prefixcmp(arg, "no-")) { | 437 | if (!prefixcmp(arg, "no-")) { |
349 | error ("did you mean `--%s` (with two dashes ?)", arg); | 438 | fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); |
350 | exit(129); | 439 | exit(129); |
351 | } | 440 | } |
352 | 441 | ||
@@ -354,14 +443,14 @@ static void check_typos(const char *arg, const struct option *options) | |||
354 | if (!options->long_name) | 443 | if (!options->long_name) |
355 | continue; | 444 | continue; |
356 | if (!prefixcmp(options->long_name, arg)) { | 445 | if (!prefixcmp(options->long_name, arg)) { |
357 | error ("did you mean `--%s` (with two dashes ?)", arg); | 446 | fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); |
358 | exit(129); | 447 | exit(129); |
359 | } | 448 | } |
360 | } | 449 | } |
361 | } | 450 | } |
362 | 451 | ||
363 | void parse_options_start(struct parse_opt_ctx_t *ctx, | 452 | static void parse_options_start(struct parse_opt_ctx_t *ctx, |
364 | int argc, const char **argv, int flags) | 453 | int argc, const char **argv, int flags) |
365 | { | 454 | { |
366 | memset(ctx, 0, sizeof(*ctx)); | 455 | memset(ctx, 0, sizeof(*ctx)); |
367 | ctx->argc = argc - 1; | 456 | ctx->argc = argc - 1; |
@@ -378,9 +467,9 @@ static int usage_with_options_internal(const char * const *, | |||
378 | const struct option *, int, | 467 | const struct option *, int, |
379 | struct parse_opt_ctx_t *); | 468 | struct parse_opt_ctx_t *); |
380 | 469 | ||
381 | int parse_options_step(struct parse_opt_ctx_t *ctx, | 470 | static int parse_options_step(struct parse_opt_ctx_t *ctx, |
382 | const struct option *options, | 471 | const struct option *options, |
383 | const char * const usagestr[]) | 472 | const char * const usagestr[]) |
384 | { | 473 | { |
385 | int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); | 474 | int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); |
386 | int excl_short_opt = 1; | 475 | int excl_short_opt = 1; |
@@ -489,7 +578,7 @@ exclusive: | |||
489 | return PARSE_OPT_HELP; | 578 | return PARSE_OPT_HELP; |
490 | } | 579 | } |
491 | 580 | ||
492 | int parse_options_end(struct parse_opt_ctx_t *ctx) | 581 | static int parse_options_end(struct parse_opt_ctx_t *ctx) |
493 | { | 582 | { |
494 | memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out)); | 583 | memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out)); |
495 | ctx->out[ctx->cpidx + ctx->argc] = NULL; | 584 | ctx->out[ctx->cpidx + ctx->argc] = NULL; |
@@ -503,18 +592,18 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o | |||
503 | 592 | ||
504 | /* build usage string if it's not provided */ | 593 | /* build usage string if it's not provided */ |
505 | if (subcommands && !usagestr[0]) { | 594 | if (subcommands && !usagestr[0]) { |
506 | struct strbuf buf = STRBUF_INIT; | 595 | char *buf = NULL; |
596 | |||
597 | astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]); | ||
507 | 598 | ||
508 | strbuf_addf(&buf, "perf %s [<options>] {", argv[0]); | ||
509 | for (int i = 0; subcommands[i]; i++) { | 599 | for (int i = 0; subcommands[i]; i++) { |
510 | if (i) | 600 | if (i) |
511 | strbuf_addstr(&buf, "|"); | 601 | astrcat(&buf, "|"); |
512 | strbuf_addstr(&buf, subcommands[i]); | 602 | astrcat(&buf, subcommands[i]); |
513 | } | 603 | } |
514 | strbuf_addstr(&buf, "}"); | 604 | astrcat(&buf, "}"); |
515 | 605 | ||
516 | usagestr[0] = strdup(buf.buf); | 606 | usagestr[0] = buf; |
517 | strbuf_release(&buf); | ||
518 | } | 607 | } |
519 | 608 | ||
520 | parse_options_start(&ctx, argc, argv, flags); | 609 | parse_options_start(&ctx, argc, argv, flags); |
@@ -539,13 +628,11 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o | |||
539 | putchar('\n'); | 628 | putchar('\n'); |
540 | exit(130); | 629 | exit(130); |
541 | default: /* PARSE_OPT_UNKNOWN */ | 630 | default: /* PARSE_OPT_UNKNOWN */ |
542 | if (ctx.argv[0][1] == '-') { | 631 | if (ctx.argv[0][1] == '-') |
543 | strbuf_addf(&error_buf, "unknown option `%s'", | 632 | astrcatf(&error_buf, "unknown option `%s'", |
544 | ctx.argv[0] + 2); | 633 | ctx.argv[0] + 2); |
545 | } else { | 634 | else |
546 | strbuf_addf(&error_buf, "unknown switch `%c'", | 635 | astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt); |
547 | *ctx.opt); | ||
548 | } | ||
549 | usage_with_options(usagestr, options); | 636 | usage_with_options(usagestr, options); |
550 | } | 637 | } |
551 | 638 | ||
@@ -645,6 +732,10 @@ static void print_option_help(const struct option *opts, int full) | |||
645 | pad = USAGE_OPTS_WIDTH; | 732 | pad = USAGE_OPTS_WIDTH; |
646 | } | 733 | } |
647 | fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); | 734 | fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); |
735 | if (opts->flags & PARSE_OPT_NOBUILD) | ||
736 | fprintf(stderr, "%*s(not built-in because %s)\n", | ||
737 | USAGE_OPTS_WIDTH + USAGE_GAP, "", | ||
738 | opts->build_opt); | ||
648 | } | 739 | } |
649 | 740 | ||
650 | static int option__cmp(const void *va, const void *vb) | 741 | static int option__cmp(const void *va, const void *vb) |
@@ -670,16 +761,18 @@ static int option__cmp(const void *va, const void *vb) | |||
670 | 761 | ||
671 | static struct option *options__order(const struct option *opts) | 762 | static struct option *options__order(const struct option *opts) |
672 | { | 763 | { |
673 | int nr_opts = 0; | 764 | int nr_opts = 0, len; |
674 | const struct option *o = opts; | 765 | const struct option *o = opts; |
675 | struct option *ordered; | 766 | struct option *ordered; |
676 | 767 | ||
677 | for (o = opts; o->type != OPTION_END; o++) | 768 | for (o = opts; o->type != OPTION_END; o++) |
678 | ++nr_opts; | 769 | ++nr_opts; |
679 | 770 | ||
680 | ordered = memdup(opts, sizeof(*o) * (nr_opts + 1)); | 771 | len = sizeof(*o) * (nr_opts + 1); |
681 | if (ordered == NULL) | 772 | ordered = malloc(len); |
773 | if (!ordered) | ||
682 | goto out; | 774 | goto out; |
775 | memcpy(ordered, opts, len); | ||
683 | 776 | ||
684 | qsort(ordered, nr_opts, sizeof(*o), option__cmp); | 777 | qsort(ordered, nr_opts, sizeof(*o), option__cmp); |
685 | out: | 778 | out: |
@@ -717,9 +810,9 @@ static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx | |||
717 | return false; | 810 | return false; |
718 | } | 811 | } |
719 | 812 | ||
720 | int usage_with_options_internal(const char * const *usagestr, | 813 | static int usage_with_options_internal(const char * const *usagestr, |
721 | const struct option *opts, int full, | 814 | const struct option *opts, int full, |
722 | struct parse_opt_ctx_t *ctx) | 815 | struct parse_opt_ctx_t *ctx) |
723 | { | 816 | { |
724 | struct option *ordered; | 817 | struct option *ordered; |
725 | 818 | ||
@@ -728,9 +821,9 @@ int usage_with_options_internal(const char * const *usagestr, | |||
728 | 821 | ||
729 | setup_pager(); | 822 | setup_pager(); |
730 | 823 | ||
731 | if (strbuf_avail(&error_buf)) { | 824 | if (error_buf) { |
732 | fprintf(stderr, " Error: %s\n", error_buf.buf); | 825 | fprintf(stderr, " Error: %s\n", error_buf); |
733 | strbuf_release(&error_buf); | 826 | zfree(&error_buf); |
734 | } | 827 | } |
735 | 828 | ||
736 | fprintf(stderr, "\n Usage: %s\n", *usagestr++); | 829 | fprintf(stderr, "\n Usage: %s\n", *usagestr++); |
@@ -774,11 +867,15 @@ void usage_with_options_msg(const char * const *usagestr, | |||
774 | const struct option *opts, const char *fmt, ...) | 867 | const struct option *opts, const char *fmt, ...) |
775 | { | 868 | { |
776 | va_list ap; | 869 | va_list ap; |
870 | char *tmp = error_buf; | ||
777 | 871 | ||
778 | va_start(ap, fmt); | 872 | va_start(ap, fmt); |
779 | strbuf_addv(&error_buf, fmt, ap); | 873 | if (vasprintf(&error_buf, fmt, ap) == -1) |
874 | die("vasprintf failed"); | ||
780 | va_end(ap); | 875 | va_end(ap); |
781 | 876 | ||
877 | free(tmp); | ||
878 | |||
782 | usage_with_options_internal(usagestr, opts, 0, NULL); | 879 | usage_with_options_internal(usagestr, opts, 0, NULL); |
783 | exit(129); | 880 | exit(129); |
784 | } | 881 | } |
@@ -848,15 +945,39 @@ int parse_opt_verbosity_cb(const struct option *opt, | |||
848 | return 0; | 945 | return 0; |
849 | } | 946 | } |
850 | 947 | ||
851 | void set_option_flag(struct option *opts, int shortopt, const char *longopt, | 948 | static struct option * |
852 | int flag) | 949 | find_option(struct option *opts, int shortopt, const char *longopt) |
853 | { | 950 | { |
854 | for (; opts->type != OPTION_END; opts++) { | 951 | for (; opts->type != OPTION_END; opts++) { |
855 | if ((shortopt && opts->short_name == shortopt) || | 952 | if ((shortopt && opts->short_name == shortopt) || |
856 | (opts->long_name && longopt && | 953 | (opts->long_name && longopt && |
857 | !strcmp(opts->long_name, longopt))) { | 954 | !strcmp(opts->long_name, longopt))) |
858 | opts->flags |= flag; | 955 | return opts; |
859 | break; | ||
860 | } | ||
861 | } | 956 | } |
957 | return NULL; | ||
958 | } | ||
959 | |||
960 | void set_option_flag(struct option *opts, int shortopt, const char *longopt, | ||
961 | int flag) | ||
962 | { | ||
963 | struct option *opt = find_option(opts, shortopt, longopt); | ||
964 | |||
965 | if (opt) | ||
966 | opt->flags |= flag; | ||
967 | return; | ||
968 | } | ||
969 | |||
970 | void set_option_nobuild(struct option *opts, int shortopt, | ||
971 | const char *longopt, | ||
972 | const char *build_opt, | ||
973 | bool can_skip) | ||
974 | { | ||
975 | struct option *opt = find_option(opts, shortopt, longopt); | ||
976 | |||
977 | if (!opt) | ||
978 | return; | ||
979 | |||
980 | opt->flags |= PARSE_OPT_NOBUILD; | ||
981 | opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0; | ||
982 | opt->build_opt = build_opt; | ||
862 | } | 983 | } |
diff --git a/tools/perf/util/parse-options.h b/tools/lib/subcmd/parse-options.h index a8e407bc251e..13a2cc1d6140 100644 --- a/tools/perf/util/parse-options.h +++ b/tools/lib/subcmd/parse-options.h | |||
@@ -1,8 +1,8 @@ | |||
1 | #ifndef __PERF_PARSE_OPTIONS_H | 1 | #ifndef __SUBCMD_PARSE_OPTIONS_H |
2 | #define __PERF_PARSE_OPTIONS_H | 2 | #define __SUBCMD_PARSE_OPTIONS_H |
3 | 3 | ||
4 | #include <linux/kernel.h> | ||
5 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | #include <stdint.h> | ||
6 | 6 | ||
7 | enum parse_opt_type { | 7 | enum parse_opt_type { |
8 | /* special types */ | 8 | /* special types */ |
@@ -41,6 +41,8 @@ enum parse_opt_option_flags { | |||
41 | PARSE_OPT_DISABLED = 32, | 41 | PARSE_OPT_DISABLED = 32, |
42 | PARSE_OPT_EXCLUSIVE = 64, | 42 | PARSE_OPT_EXCLUSIVE = 64, |
43 | PARSE_OPT_NOEMPTY = 128, | 43 | PARSE_OPT_NOEMPTY = 128, |
44 | PARSE_OPT_NOBUILD = 256, | ||
45 | PARSE_OPT_CANSKIP = 512, | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | struct option; | 48 | struct option; |
@@ -96,6 +98,7 @@ struct option { | |||
96 | void *value; | 98 | void *value; |
97 | const char *argh; | 99 | const char *argh; |
98 | const char *help; | 100 | const char *help; |
101 | const char *build_opt; | ||
99 | 102 | ||
100 | int flags; | 103 | int flags; |
101 | parse_opt_cb *callback; | 104 | parse_opt_cb *callback; |
@@ -149,6 +152,9 @@ struct option { | |||
149 | /* parse_options() will filter out the processed options and leave the | 152 | /* parse_options() will filter out the processed options and leave the |
150 | * non-option argments in argv[]. | 153 | * non-option argments in argv[]. |
151 | * Returns the number of arguments left in argv[]. | 154 | * Returns the number of arguments left in argv[]. |
155 | * | ||
156 | * NOTE: parse_options() and parse_options_subcommand() may call exit() in the | ||
157 | * case of an error (or for 'special' options like --list-cmds or --list-opts). | ||
152 | */ | 158 | */ |
153 | extern int parse_options(int argc, const char **argv, | 159 | extern int parse_options(int argc, const char **argv, |
154 | const struct option *options, | 160 | const struct option *options, |
@@ -195,15 +201,6 @@ extern int parse_options_usage(const char * const *usagestr, | |||
195 | const char *optstr, | 201 | const char *optstr, |
196 | bool short_opt); | 202 | bool short_opt); |
197 | 203 | ||
198 | extern void parse_options_start(struct parse_opt_ctx_t *ctx, | ||
199 | int argc, const char **argv, int flags); | ||
200 | |||
201 | extern int parse_options_step(struct parse_opt_ctx_t *ctx, | ||
202 | const struct option *options, | ||
203 | const char * const usagestr[]); | ||
204 | |||
205 | extern int parse_options_end(struct parse_opt_ctx_t *ctx); | ||
206 | |||
207 | 204 | ||
208 | /*----- some often used options -----*/ | 205 | /*----- some often used options -----*/ |
209 | extern int parse_opt_abbrev_cb(const struct option *, const char *, int); | 206 | extern int parse_opt_abbrev_cb(const struct option *, const char *, int); |
@@ -226,4 +223,7 @@ extern int parse_opt_verbosity_cb(const struct option *, const char *, int); | |||
226 | extern const char *parse_options_fix_filename(const char *prefix, const char *file); | 223 | extern const char *parse_options_fix_filename(const char *prefix, const char *file); |
227 | 224 | ||
228 | void set_option_flag(struct option *opts, int sopt, const char *lopt, int flag); | 225 | void set_option_flag(struct option *opts, int sopt, const char *lopt, int flag); |
229 | #endif /* __PERF_PARSE_OPTIONS_H */ | 226 | void set_option_nobuild(struct option *opts, int shortopt, const char *longopt, |
227 | const char *build_opt, bool can_skip); | ||
228 | |||
229 | #endif /* __SUBCMD_PARSE_OPTIONS_H */ | ||
diff --git a/tools/perf/util/run-command.c b/tools/lib/subcmd/run-command.c index 34622b53e733..f4f6c9eb8e59 100644 --- a/tools/perf/util/run-command.c +++ b/tools/lib/subcmd/run-command.c | |||
@@ -1,7 +1,15 @@ | |||
1 | #include "cache.h" | 1 | #include <unistd.h> |
2 | #include <sys/types.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <fcntl.h> | ||
5 | #include <string.h> | ||
6 | #include <errno.h> | ||
7 | #include <sys/wait.h> | ||
8 | #include "subcmd-util.h" | ||
2 | #include "run-command.h" | 9 | #include "run-command.h" |
3 | #include "exec_cmd.h" | 10 | #include "exec-cmd.h" |
4 | #include "debug.h" | 11 | |
12 | #define STRERR_BUFSIZE 128 | ||
5 | 13 | ||
6 | static inline void close_pair(int fd[2]) | 14 | static inline void close_pair(int fd[2]) |
7 | { | 15 | { |
@@ -112,8 +120,8 @@ int start_command(struct child_process *cmd) | |||
112 | } | 120 | } |
113 | if (cmd->preexec_cb) | 121 | if (cmd->preexec_cb) |
114 | cmd->preexec_cb(); | 122 | cmd->preexec_cb(); |
115 | if (cmd->perf_cmd) { | 123 | if (cmd->exec_cmd) { |
116 | execv_perf_cmd(cmd->argv); | 124 | execv_cmd(cmd->argv); |
117 | } else { | 125 | } else { |
118 | execvp(cmd->argv[0], (char *const*) cmd->argv); | 126 | execvp(cmd->argv[0], (char *const*) cmd->argv); |
119 | } | 127 | } |
@@ -164,8 +172,8 @@ static int wait_or_whine(pid_t pid) | |||
164 | if (waiting < 0) { | 172 | if (waiting < 0) { |
165 | if (errno == EINTR) | 173 | if (errno == EINTR) |
166 | continue; | 174 | continue; |
167 | error("waitpid failed (%s)", | 175 | fprintf(stderr, " Error: waitpid failed (%s)", |
168 | strerror_r(errno, sbuf, sizeof(sbuf))); | 176 | strerror_r(errno, sbuf, sizeof(sbuf))); |
169 | return -ERR_RUN_COMMAND_WAITPID; | 177 | return -ERR_RUN_COMMAND_WAITPID; |
170 | } | 178 | } |
171 | if (waiting != pid) | 179 | if (waiting != pid) |
@@ -207,7 +215,7 @@ static void prepare_run_command_v_opt(struct child_process *cmd, | |||
207 | memset(cmd, 0, sizeof(*cmd)); | 215 | memset(cmd, 0, sizeof(*cmd)); |
208 | cmd->argv = argv; | 216 | cmd->argv = argv; |
209 | cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; | 217 | cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; |
210 | cmd->perf_cmd = opt & RUN_PERF_CMD ? 1 : 0; | 218 | cmd->exec_cmd = opt & RUN_EXEC_CMD ? 1 : 0; |
211 | cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; | 219 | cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; |
212 | } | 220 | } |
213 | 221 | ||
diff --git a/tools/perf/util/run-command.h b/tools/lib/subcmd/run-command.h index 1ef264d5069c..fe2befea1e73 100644 --- a/tools/perf/util/run-command.h +++ b/tools/lib/subcmd/run-command.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef __PERF_RUN_COMMAND_H | 1 | #ifndef __SUBCMD_RUN_COMMAND_H |
2 | #define __PERF_RUN_COMMAND_H | 2 | #define __SUBCMD_RUN_COMMAND_H |
3 | |||
4 | #include <unistd.h> | ||
3 | 5 | ||
4 | enum { | 6 | enum { |
5 | ERR_RUN_COMMAND_FORK = 10000, | 7 | ERR_RUN_COMMAND_FORK = 10000, |
@@ -41,7 +43,7 @@ struct child_process { | |||
41 | unsigned no_stdin:1; | 43 | unsigned no_stdin:1; |
42 | unsigned no_stdout:1; | 44 | unsigned no_stdout:1; |
43 | unsigned no_stderr:1; | 45 | unsigned no_stderr:1; |
44 | unsigned perf_cmd:1; /* if this is to be perf sub-command */ | 46 | unsigned exec_cmd:1; /* if this is to be external sub-command */ |
45 | unsigned stdout_to_stderr:1; | 47 | unsigned stdout_to_stderr:1; |
46 | void (*preexec_cb)(void); | 48 | void (*preexec_cb)(void); |
47 | }; | 49 | }; |
@@ -51,8 +53,8 @@ int finish_command(struct child_process *); | |||
51 | int run_command(struct child_process *); | 53 | int run_command(struct child_process *); |
52 | 54 | ||
53 | #define RUN_COMMAND_NO_STDIN 1 | 55 | #define RUN_COMMAND_NO_STDIN 1 |
54 | #define RUN_PERF_CMD 2 /*If this is to be perf sub-command */ | 56 | #define RUN_EXEC_CMD 2 /*If this is to be external sub-command */ |
55 | #define RUN_COMMAND_STDOUT_TO_STDERR 4 | 57 | #define RUN_COMMAND_STDOUT_TO_STDERR 4 |
56 | int run_command_v_opt(const char **argv, int opt); | 58 | int run_command_v_opt(const char **argv, int opt); |
57 | 59 | ||
58 | #endif /* __PERF_RUN_COMMAND_H */ | 60 | #endif /* __SUBCMD_RUN_COMMAND_H */ |
diff --git a/tools/perf/util/sigchain.c b/tools/lib/subcmd/sigchain.c index ba785e9b1841..3537c348a18e 100644 --- a/tools/perf/util/sigchain.c +++ b/tools/lib/subcmd/sigchain.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <signal.h> | ||
2 | #include "subcmd-util.h" | ||
1 | #include "sigchain.h" | 3 | #include "sigchain.h" |
2 | #include "cache.h" | ||
3 | 4 | ||
4 | #define SIGCHAIN_MAX_SIGNALS 32 | 5 | #define SIGCHAIN_MAX_SIGNALS 32 |
5 | 6 | ||
diff --git a/tools/perf/util/sigchain.h b/tools/lib/subcmd/sigchain.h index 959d64eb5557..0c919f2874ca 100644 --- a/tools/perf/util/sigchain.h +++ b/tools/lib/subcmd/sigchain.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef __PERF_SIGCHAIN_H | 1 | #ifndef __SUBCMD_SIGCHAIN_H |
2 | #define __PERF_SIGCHAIN_H | 2 | #define __SUBCMD_SIGCHAIN_H |
3 | 3 | ||
4 | typedef void (*sigchain_fun)(int); | 4 | typedef void (*sigchain_fun)(int); |
5 | 5 | ||
@@ -7,4 +7,4 @@ int sigchain_pop(int sig); | |||
7 | 7 | ||
8 | void sigchain_push_common(sigchain_fun f); | 8 | void sigchain_push_common(sigchain_fun f); |
9 | 9 | ||
10 | #endif /* __PERF_SIGCHAIN_H */ | 10 | #endif /* __SUBCMD_SIGCHAIN_H */ |
diff --git a/tools/lib/subcmd/subcmd-config.c b/tools/lib/subcmd/subcmd-config.c new file mode 100644 index 000000000000..d017c728bd1b --- /dev/null +++ b/tools/lib/subcmd/subcmd-config.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include "subcmd-config.h" | ||
2 | |||
3 | #define UNDEFINED "SUBCMD_HAS_NOT_BEEN_INITIALIZED" | ||
4 | |||
5 | struct subcmd_config subcmd_config = { | ||
6 | .exec_name = UNDEFINED, | ||
7 | .prefix = UNDEFINED, | ||
8 | .exec_path = UNDEFINED, | ||
9 | .exec_path_env = UNDEFINED, | ||
10 | .pager_env = UNDEFINED, | ||
11 | }; | ||
diff --git a/tools/lib/subcmd/subcmd-config.h b/tools/lib/subcmd/subcmd-config.h new file mode 100644 index 000000000000..cc8514030b5c --- /dev/null +++ b/tools/lib/subcmd/subcmd-config.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __PERF_SUBCMD_CONFIG_H | ||
2 | #define __PERF_SUBCMD_CONFIG_H | ||
3 | |||
4 | struct subcmd_config { | ||
5 | const char *exec_name; | ||
6 | const char *prefix; | ||
7 | const char *exec_path; | ||
8 | const char *exec_path_env; | ||
9 | const char *pager_env; | ||
10 | }; | ||
11 | |||
12 | extern struct subcmd_config subcmd_config; | ||
13 | |||
14 | #endif /* __PERF_SUBCMD_CONFIG_H */ | ||
diff --git a/tools/lib/subcmd/subcmd-util.h b/tools/lib/subcmd/subcmd-util.h new file mode 100644 index 000000000000..fc2e45d8aaf1 --- /dev/null +++ b/tools/lib/subcmd/subcmd-util.h | |||
@@ -0,0 +1,91 @@ | |||
1 | #ifndef __SUBCMD_UTIL_H | ||
2 | #define __SUBCMD_UTIL_H | ||
3 | |||
4 | #include <stdarg.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <stdio.h> | ||
7 | |||
8 | #define NORETURN __attribute__((__noreturn__)) | ||
9 | |||
10 | static inline void report(const char *prefix, const char *err, va_list params) | ||
11 | { | ||
12 | char msg[1024]; | ||
13 | vsnprintf(msg, sizeof(msg), err, params); | ||
14 | fprintf(stderr, " %s%s\n", prefix, msg); | ||
15 | } | ||
16 | |||
17 | static NORETURN inline void die(const char *err, ...) | ||
18 | { | ||
19 | va_list params; | ||
20 | |||
21 | va_start(params, err); | ||
22 | report(" Fatal: ", err, params); | ||
23 | exit(128); | ||
24 | va_end(params); | ||
25 | } | ||
26 | |||
27 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) | ||
28 | |||
29 | #define alloc_nr(x) (((x)+16)*3/2) | ||
30 | |||
31 | /* | ||
32 | * Realloc the buffer pointed at by variable 'x' so that it can hold | ||
33 | * at least 'nr' entries; the number of entries currently allocated | ||
34 | * is 'alloc', using the standard growing factor alloc_nr() macro. | ||
35 | * | ||
36 | * DO NOT USE any expression with side-effect for 'x' or 'alloc'. | ||
37 | */ | ||
38 | #define ALLOC_GROW(x, nr, alloc) \ | ||
39 | do { \ | ||
40 | if ((nr) > alloc) { \ | ||
41 | if (alloc_nr(alloc) < (nr)) \ | ||
42 | alloc = (nr); \ | ||
43 | else \ | ||
44 | alloc = alloc_nr(alloc); \ | ||
45 | x = xrealloc((x), alloc * sizeof(*(x))); \ | ||
46 | } \ | ||
47 | } while(0) | ||
48 | |||
49 | static inline void *xrealloc(void *ptr, size_t size) | ||
50 | { | ||
51 | void *ret = realloc(ptr, size); | ||
52 | if (!ret && !size) | ||
53 | ret = realloc(ptr, 1); | ||
54 | if (!ret) { | ||
55 | ret = realloc(ptr, size); | ||
56 | if (!ret && !size) | ||
57 | ret = realloc(ptr, 1); | ||
58 | if (!ret) | ||
59 | die("Out of memory, realloc failed"); | ||
60 | } | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | #define astrcatf(out, fmt, ...) \ | ||
65 | ({ \ | ||
66 | char *tmp = *(out); \ | ||
67 | if (asprintf((out), "%s" fmt, tmp ?: "", ## __VA_ARGS__) == -1) \ | ||
68 | die("asprintf failed"); \ | ||
69 | free(tmp); \ | ||
70 | }) | ||
71 | |||
72 | static inline void astrcat(char **out, const char *add) | ||
73 | { | ||
74 | char *tmp = *out; | ||
75 | |||
76 | if (asprintf(out, "%s%s", tmp ?: "", add) == -1) | ||
77 | die("asprintf failed"); | ||
78 | |||
79 | free(tmp); | ||
80 | } | ||
81 | |||
82 | static inline int prefixcmp(const char *str, const char *prefix) | ||
83 | { | ||
84 | for (; ; str++, prefix++) | ||
85 | if (!*prefix) | ||
86 | return 0; | ||
87 | else if (*str != *prefix) | ||
88 | return (unsigned char)*prefix - (unsigned char)*str; | ||
89 | } | ||
90 | |||
91 | #endif /* __SUBCMD_UTIL_H */ | ||
diff --git a/tools/perf/Build b/tools/perf/Build index 2a41217e9d88..00c4b8c3d8ca 100644 --- a/tools/perf/Build +++ b/tools/perf/Build | |||
@@ -36,7 +36,10 @@ paths += -DPERF_MAN_PATH="BUILD_STR($(mandir_SQ))" | |||
36 | 36 | ||
37 | CFLAGS_builtin-help.o += $(paths) | 37 | CFLAGS_builtin-help.o += $(paths) |
38 | CFLAGS_builtin-timechart.o += $(paths) | 38 | CFLAGS_builtin-timechart.o += $(paths) |
39 | CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" -include $(OUTPUT)PERF-VERSION-FILE | 39 | CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \ |
40 | -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" \ | ||
41 | -DPREFIX="BUILD_STR($(prefix_SQ))" \ | ||
42 | -include $(OUTPUT)PERF-VERSION-FILE | ||
40 | CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" | 43 | CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" |
41 | 44 | ||
42 | libperf-y += util/ | 45 | libperf-y += util/ |
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index e630a7d2c348..3a1a32f5479f 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -207,11 +207,23 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0- | |||
207 | In per-thread mode with inheritance mode on (default), samples are captured only when | 207 | In per-thread mode with inheritance mode on (default), samples are captured only when |
208 | the thread executes on the designated CPUs. Default is to monitor all CPUs. | 208 | the thread executes on the designated CPUs. Default is to monitor all CPUs. |
209 | 209 | ||
210 | -B:: | ||
211 | --no-buildid:: | ||
212 | Do not save the build ids of binaries in the perf.data files. This skips | ||
213 | post processing after recording, which sometimes makes the final step in | ||
214 | the recording process to take a long time, as it needs to process all | ||
215 | events looking for mmap records. The downside is that it can misresolve | ||
216 | symbols if the workload binaries used when recording get locally rebuilt | ||
217 | or upgraded, because the only key available in this case is the | ||
218 | pathname. You can also set the "record.build-id" config variable to | ||
219 | 'skip to have this behaviour permanently. | ||
220 | |||
210 | -N:: | 221 | -N:: |
211 | --no-buildid-cache:: | 222 | --no-buildid-cache:: |
212 | Do not update the buildid cache. This saves some overhead in situations | 223 | Do not update the buildid cache. This saves some overhead in situations |
213 | where the information in the perf.data file (which includes buildids) | 224 | where the information in the perf.data file (which includes buildids) |
214 | is sufficient. | 225 | is sufficient. You can also set the "record.build-id" config variable to |
226 | 'no-cache' to have the same effect. | ||
215 | 227 | ||
216 | -G name,...:: | 228 | -G name,...:: |
217 | --cgroup name,...:: | 229 | --cgroup name,...:: |
@@ -314,11 +326,17 @@ This option sets the time out limit. The default value is 500 ms. | |||
314 | Record context switch events i.e. events of type PERF_RECORD_SWITCH or | 326 | Record context switch events i.e. events of type PERF_RECORD_SWITCH or |
315 | PERF_RECORD_SWITCH_CPU_WIDE. | 327 | PERF_RECORD_SWITCH_CPU_WIDE. |
316 | 328 | ||
317 | --clang-path:: | 329 | --clang-path=PATH:: |
318 | Path to clang binary to use for compiling BPF scriptlets. | 330 | Path to clang binary to use for compiling BPF scriptlets. |
331 | (enabled when BPF support is on) | ||
319 | 332 | ||
320 | --clang-opt:: | 333 | --clang-opt=OPTIONS:: |
321 | Options passed to clang when compiling BPF scriptlets. | 334 | Options passed to clang when compiling BPF scriptlets. |
335 | (enabled when BPF support is on) | ||
336 | |||
337 | --vmlinux=PATH:: | ||
338 | Specify vmlinux path which has debuginfo. | ||
339 | (enabled when BPF prologue is on) | ||
322 | 340 | ||
323 | SEE ALSO | 341 | SEE ALSO |
324 | -------- | 342 | -------- |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 2562eac6451d..ce3932ee4893 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -20,6 +20,7 @@ tools/lib/traceevent | |||
20 | tools/lib/bpf | 20 | tools/lib/bpf |
21 | tools/lib/api | 21 | tools/lib/api |
22 | tools/lib/bpf | 22 | tools/lib/bpf |
23 | tools/lib/subcmd | ||
23 | tools/lib/hweight.c | 24 | tools/lib/hweight.c |
24 | tools/lib/rbtree.c | 25 | tools/lib/rbtree.c |
25 | tools/lib/string.c | 26 | tools/lib/string.c |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 929a32ba15f5..569fcf022531 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -145,9 +145,10 @@ BISON = bison | |||
145 | STRIP = strip | 145 | STRIP = strip |
146 | AWK = awk | 146 | AWK = awk |
147 | 147 | ||
148 | LIB_DIR = $(srctree)/tools/lib/api/ | 148 | LIB_DIR = $(srctree)/tools/lib/api/ |
149 | TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ | 149 | TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ |
150 | BPF_DIR = $(srctree)/tools/lib/bpf/ | 150 | BPF_DIR = $(srctree)/tools/lib/bpf/ |
151 | SUBCMD_DIR = $(srctree)/tools/lib/subcmd/ | ||
151 | 152 | ||
152 | # include config/Makefile by default and rule out | 153 | # include config/Makefile by default and rule out |
153 | # non-config cases | 154 | # non-config cases |
@@ -184,15 +185,17 @@ strip-libs = $(filter-out -l%,$(1)) | |||
184 | ifneq ($(OUTPUT),) | 185 | ifneq ($(OUTPUT),) |
185 | TE_PATH=$(OUTPUT) | 186 | TE_PATH=$(OUTPUT) |
186 | BPF_PATH=$(OUTPUT) | 187 | BPF_PATH=$(OUTPUT) |
188 | SUBCMD_PATH=$(OUTPUT) | ||
187 | ifneq ($(subdir),) | 189 | ifneq ($(subdir),) |
188 | LIB_PATH=$(OUTPUT)/../lib/api/ | 190 | API_PATH=$(OUTPUT)/../lib/api/ |
189 | else | 191 | else |
190 | LIB_PATH=$(OUTPUT) | 192 | API_PATH=$(OUTPUT) |
191 | endif | 193 | endif |
192 | else | 194 | else |
193 | TE_PATH=$(TRACE_EVENT_DIR) | 195 | TE_PATH=$(TRACE_EVENT_DIR) |
194 | LIB_PATH=$(LIB_DIR) | 196 | API_PATH=$(LIB_DIR) |
195 | BPF_PATH=$(BPF_DIR) | 197 | BPF_PATH=$(BPF_DIR) |
198 | SUBCMD_PATH=$(SUBCMD_DIR) | ||
196 | endif | 199 | endif |
197 | 200 | ||
198 | LIBTRACEEVENT = $(TE_PATH)libtraceevent.a | 201 | LIBTRACEEVENT = $(TE_PATH)libtraceevent.a |
@@ -201,11 +204,13 @@ export LIBTRACEEVENT | |||
201 | LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list | 204 | LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list |
202 | LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) | 205 | LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) |
203 | 206 | ||
204 | LIBAPI = $(LIB_PATH)libapi.a | 207 | LIBAPI = $(API_PATH)libapi.a |
205 | export LIBAPI | 208 | export LIBAPI |
206 | 209 | ||
207 | LIBBPF = $(BPF_PATH)libbpf.a | 210 | LIBBPF = $(BPF_PATH)libbpf.a |
208 | 211 | ||
212 | LIBSUBCMD = $(SUBCMD_PATH)libsubcmd.a | ||
213 | |||
209 | # python extension build directories | 214 | # python extension build directories |
210 | PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ | 215 | PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ |
211 | PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ | 216 | PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ |
@@ -257,7 +262,7 @@ export PERL_PATH | |||
257 | 262 | ||
258 | LIB_FILE=$(OUTPUT)libperf.a | 263 | LIB_FILE=$(OUTPUT)libperf.a |
259 | 264 | ||
260 | PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT) | 265 | PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD) |
261 | ifndef NO_LIBBPF | 266 | ifndef NO_LIBBPF |
262 | PERFLIBS += $(LIBBPF) | 267 | PERFLIBS += $(LIBBPF) |
263 | endif | 268 | endif |
@@ -437,6 +442,13 @@ $(LIBBPF)-clean: | |||
437 | $(call QUIET_CLEAN, libbpf) | 442 | $(call QUIET_CLEAN, libbpf) |
438 | $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null | 443 | $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null |
439 | 444 | ||
445 | $(LIBSUBCMD): fixdep FORCE | ||
446 | $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a | ||
447 | |||
448 | $(LIBSUBCMD)-clean: | ||
449 | $(call QUIET_CLEAN, libsubcmd) | ||
450 | $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) clean | ||
451 | |||
440 | help: | 452 | help: |
441 | @echo 'Perf make targets:' | 453 | @echo 'Perf make targets:' |
442 | @echo ' doc - make *all* documentation (see below)' | 454 | @echo ' doc - make *all* documentation (see below)' |
@@ -582,15 +594,16 @@ $(INSTALL_DOC_TARGETS): | |||
582 | # | 594 | # |
583 | config-clean: | 595 | config-clean: |
584 | $(call QUIET_CLEAN, config) | 596 | $(call QUIET_CLEAN, config) |
585 | $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null | 597 | $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null |
586 | 598 | ||
587 | clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean config-clean | 599 | clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean |
588 | $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) | 600 | $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) |
589 | $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete | 601 | $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete |
590 | $(Q)$(RM) $(OUTPUT).config-detected | 602 | $(Q)$(RM) $(OUTPUT).config-detected |
591 | $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 | 603 | $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 |
592 | $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ | 604 | $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ |
593 | $(OUTPUT)util/intel-pt-decoder/inat-tables.c | 605 | $(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \ |
606 | $(OUTPUT)tests/llvm-src-{base,kbuild,prologue}.c | ||
594 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean | 607 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean |
595 | $(python-clean) | 608 | $(python-clean) |
596 | 609 | ||
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index b02af064f0f9..b64d46285ebb 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "../../util/evlist.h" | 26 | #include "../../util/evlist.h" |
27 | #include "../../util/evsel.h" | 27 | #include "../../util/evsel.h" |
28 | #include "../../util/cpumap.h" | 28 | #include "../../util/cpumap.h" |
29 | #include "../../util/parse-options.h" | 29 | #include <subcmd/parse-options.h> |
30 | #include "../../util/parse-events.h" | 30 | #include "../../util/parse-events.h" |
31 | #include "../../util/pmu.h" | 31 | #include "../../util/pmu.h" |
32 | #include "../../util/debug.h" | 32 | #include "../../util/debug.h" |
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index fc9bebd2cca0..0999ac536d86 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include "../perf.h" | 11 | #include "../perf.h" |
12 | #include "../util/util.h" | 12 | #include "../util/util.h" |
13 | #include "../util/stat.h" | 13 | #include "../util/stat.h" |
14 | #include "../util/parse-options.h" | 14 | #include <subcmd/parse-options.h> |
15 | #include "../util/header.h" | 15 | #include "../util/header.h" |
16 | #include "bench.h" | 16 | #include "bench.h" |
17 | #include "futex.h" | 17 | #include "futex.h" |
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index bc6a16adbca8..6a18ce21f865 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include "../perf.h" | 5 | #include "../perf.h" |
6 | #include "../util/util.h" | 6 | #include "../util/util.h" |
7 | #include "../util/stat.h" | 7 | #include "../util/stat.h" |
8 | #include "../util/parse-options.h" | 8 | #include <subcmd/parse-options.h> |
9 | #include "../util/header.h" | 9 | #include "../util/header.h" |
10 | #include "bench.h" | 10 | #include "bench.h" |
11 | #include "futex.h" | 11 | #include "futex.h" |
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index ad0d9b5342fb..718238683013 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include "../perf.h" | 11 | #include "../perf.h" |
12 | #include "../util/util.h" | 12 | #include "../util/util.h" |
13 | #include "../util/stat.h" | 13 | #include "../util/stat.h" |
14 | #include "../util/parse-options.h" | 14 | #include <subcmd/parse-options.h> |
15 | #include "../util/header.h" | 15 | #include "../util/header.h" |
16 | #include "bench.h" | 16 | #include "bench.h" |
17 | #include "futex.h" | 17 | #include "futex.h" |
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 6d8c9fa2a16c..91aaf2a1fa90 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "../perf.h" | 10 | #include "../perf.h" |
11 | #include "../util/util.h" | 11 | #include "../util/util.h" |
12 | #include "../util/stat.h" | 12 | #include "../util/stat.h" |
13 | #include "../util/parse-options.h" | 13 | #include <subcmd/parse-options.h> |
14 | #include "../util/header.h" | 14 | #include "../util/header.h" |
15 | #include "bench.h" | 15 | #include "bench.h" |
16 | #include "futex.h" | 16 | #include "futex.h" |
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index e5e41d3bdce7..f416bd705f66 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include "../perf.h" | 11 | #include "../perf.h" |
12 | #include "../util/util.h" | 12 | #include "../util/util.h" |
13 | #include "../util/stat.h" | 13 | #include "../util/stat.h" |
14 | #include "../util/parse-options.h" | 14 | #include <subcmd/parse-options.h> |
15 | #include "../util/header.h" | 15 | #include "../util/header.h" |
16 | #include "bench.h" | 16 | #include "bench.h" |
17 | #include "futex.h" | 17 | #include "futex.h" |
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c index 9419b944220f..a91aa85d80ff 100644 --- a/tools/perf/bench/mem-functions.c +++ b/tools/perf/bench/mem-functions.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #include "../perf.h" | 9 | #include "../perf.h" |
10 | #include "../util/util.h" | 10 | #include "../util/util.h" |
11 | #include "../util/parse-options.h" | 11 | #include <subcmd/parse-options.h> |
12 | #include "../util/header.h" | 12 | #include "../util/header.h" |
13 | #include "../util/cloexec.h" | 13 | #include "../util/cloexec.h" |
14 | #include "bench.h" | 14 | #include "bench.h" |
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 492df2752a2d..5049d6357a46 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include "../perf.h" | 7 | #include "../perf.h" |
8 | #include "../builtin.h" | 8 | #include "../builtin.h" |
9 | #include "../util/util.h" | 9 | #include "../util/util.h" |
10 | #include "../util/parse-options.h" | 10 | #include <subcmd/parse-options.h> |
11 | #include "../util/cloexec.h" | 11 | #include "../util/cloexec.h" |
12 | 12 | ||
13 | #include "bench.h" | 13 | #include "bench.h" |
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index d4ff1b539cfd..bfaf9503de8e 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #include "../perf.h" | 12 | #include "../perf.h" |
13 | #include "../util/util.h" | 13 | #include "../util/util.h" |
14 | #include "../util/parse-options.h" | 14 | #include <subcmd/parse-options.h> |
15 | #include "../builtin.h" | 15 | #include "../builtin.h" |
16 | #include "bench.h" | 16 | #include "bench.h" |
17 | 17 | ||
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 005cc283790c..1dc2d13cc272 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | #include "../perf.h" | 11 | #include "../perf.h" |
12 | #include "../util/util.h" | 12 | #include "../util/util.h" |
13 | #include "../util/parse-options.h" | 13 | #include <subcmd/parse-options.h> |
14 | #include "../builtin.h" | 14 | #include "../builtin.h" |
15 | #include "bench.h" | 15 | #include "bench.h" |
16 | 16 | ||
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 1f00dc7cecba..e18f1b995ffd 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "util/evsel.h" | 21 | #include "util/evsel.h" |
22 | #include "util/annotate.h" | 22 | #include "util/annotate.h" |
23 | #include "util/event.h" | 23 | #include "util/event.h" |
24 | #include "util/parse-options.h" | 24 | #include <subcmd/parse-options.h> |
25 | #include "util/parse-events.h" | 25 | #include "util/parse-events.h" |
26 | #include "util/thread.h" | 26 | #include "util/thread.h" |
27 | #include "util/sort.h" | 27 | #include "util/sort.h" |
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index b17aed36ca16..a1cddc6bbf0f 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | #include "perf.h" | 17 | #include "perf.h" |
18 | #include "util/util.h" | 18 | #include "util/util.h" |
19 | #include "util/parse-options.h" | 19 | #include <subcmd/parse-options.h> |
20 | #include "builtin.h" | 20 | #include "builtin.h" |
21 | #include "bench/bench.h" | 21 | #include "bench/bench.h" |
22 | 22 | ||
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 7b8450cd33c2..d93bff7fc0e4 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include "util/cache.h" | 16 | #include "util/cache.h" |
17 | #include "util/debug.h" | 17 | #include "util/debug.h" |
18 | #include "util/header.h" | 18 | #include "util/header.h" |
19 | #include "util/parse-options.h" | 19 | #include <subcmd/parse-options.h> |
20 | #include "util/strlist.h" | 20 | #include "util/strlist.h" |
21 | #include "util/build-id.h" | 21 | #include "util/build-id.h" |
22 | #include "util/session.h" | 22 | #include "util/session.h" |
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 6419f57b0850..5e914ee79eb3 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "util/build-id.h" | 12 | #include "util/build-id.h" |
13 | #include "util/cache.h" | 13 | #include "util/cache.h" |
14 | #include "util/debug.h" | 14 | #include "util/debug.h" |
15 | #include "util/parse-options.h" | 15 | #include <subcmd/parse-options.h> |
16 | #include "util/session.h" | 16 | #include "util/session.h" |
17 | #include "util/symbol.h" | 17 | #include "util/symbol.h" |
18 | #include "util/data.h" | 18 | #include "util/data.h" |
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 427ea7a705b8..f04e804a9fad 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include "perf.h" | 9 | #include "perf.h" |
10 | 10 | ||
11 | #include "util/cache.h" | 11 | #include "util/cache.h" |
12 | #include "util/parse-options.h" | 12 | #include <subcmd/parse-options.h> |
13 | #include "util/util.h" | 13 | #include "util/util.h" |
14 | #include "util/debug.h" | 14 | #include "util/debug.h" |
15 | 15 | ||
diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index d6525bc54d13..b97bc1518b44 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c | |||
@@ -2,7 +2,7 @@ | |||
2 | #include "builtin.h" | 2 | #include "builtin.h" |
3 | #include "perf.h" | 3 | #include "perf.h" |
4 | #include "debug.h" | 4 | #include "debug.h" |
5 | #include "parse-options.h" | 5 | #include <subcmd/parse-options.h> |
6 | #include "data-convert-bt.h" | 6 | #include "data-convert-bt.h" |
7 | 7 | ||
8 | typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix); | 8 | typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix); |
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index f4d62510acbb..08a7d36a2cf8 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "util/evlist.h" | 12 | #include "util/evlist.h" |
13 | #include "util/evsel.h" | 13 | #include "util/evsel.h" |
14 | #include "util/parse-events.h" | 14 | #include "util/parse-events.h" |
15 | #include "util/parse-options.h" | 15 | #include <subcmd/parse-options.h> |
16 | #include "util/session.h" | 16 | #include "util/session.h" |
17 | #include "util/data.h" | 17 | #include "util/data.h" |
18 | #include "util/debug.h" | 18 | #include "util/debug.h" |
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index a7d588bf3cdd..96c1a4cfbbbf 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c | |||
@@ -6,11 +6,11 @@ | |||
6 | #include "perf.h" | 6 | #include "perf.h" |
7 | #include "util/cache.h" | 7 | #include "util/cache.h" |
8 | #include "builtin.h" | 8 | #include "builtin.h" |
9 | #include "util/exec_cmd.h" | 9 | #include <subcmd/exec-cmd.h> |
10 | #include "common-cmds.h" | 10 | #include "common-cmds.h" |
11 | #include "util/parse-options.h" | 11 | #include <subcmd/parse-options.h> |
12 | #include "util/run-command.h" | 12 | #include <subcmd/run-command.h> |
13 | #include "util/help.h" | 13 | #include <subcmd/help.h> |
14 | #include "util/debug.h" | 14 | #include "util/debug.h" |
15 | 15 | ||
16 | static struct man_viewer_list { | 16 | static struct man_viewer_list { |
@@ -407,7 +407,7 @@ static int get_html_page_path(struct strbuf *page_path, const char *page) | |||
407 | #ifndef open_html | 407 | #ifndef open_html |
408 | static void open_html(const char *path) | 408 | static void open_html(const char *path) |
409 | { | 409 | { |
410 | execl_perf_cmd("web--browse", "-c", "help.browser", path, NULL); | 410 | execl_cmd("web--browse", "-c", "help.browser", path, NULL); |
411 | } | 411 | } |
412 | #endif | 412 | #endif |
413 | 413 | ||
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 99d127fe9c35..0022e02ed31a 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "util/data.h" | 18 | #include "util/data.h" |
19 | #include "util/auxtrace.h" | 19 | #include "util/auxtrace.h" |
20 | 20 | ||
21 | #include "util/parse-options.h" | 21 | #include <subcmd/parse-options.h> |
22 | 22 | ||
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | 24 | ||
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 93ce665f976f..118010553d0c 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "util/tool.h" | 12 | #include "util/tool.h" |
13 | #include "util/callchain.h" | 13 | #include "util/callchain.h" |
14 | 14 | ||
15 | #include "util/parse-options.h" | 15 | #include <subcmd/parse-options.h> |
16 | #include "util/trace-event.h" | 16 | #include "util/trace-event.h" |
17 | #include "util/data.h" | 17 | #include "util/data.h" |
18 | #include "util/cpumap.h" | 18 | #include "util/cpumap.h" |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 031f9f55c281..4418d9214872 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "util/header.h" | 10 | #include "util/header.h" |
11 | #include "util/session.h" | 11 | #include "util/session.h" |
12 | #include "util/intlist.h" | 12 | #include "util/intlist.h" |
13 | #include "util/parse-options.h" | 13 | #include <subcmd/parse-options.h> |
14 | #include "util/trace-event.h" | 14 | #include "util/trace-event.h" |
15 | #include "util/debug.h" | 15 | #include "util/debug.h" |
16 | #include "util/tool.h" | 16 | #include "util/tool.h" |
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index bf679e2c978b..5e22db4684b8 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include "util/parse-events.h" | 14 | #include "util/parse-events.h" |
15 | #include "util/cache.h" | 15 | #include "util/cache.h" |
16 | #include "util/pmu.h" | 16 | #include "util/pmu.h" |
17 | #include "util/parse-options.h" | 17 | #include <subcmd/parse-options.h> |
18 | 18 | ||
19 | int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) | 19 | int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) |
20 | { | 20 | { |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index de16aaed516e..ce3bfb48b26f 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include "util/thread.h" | 9 | #include "util/thread.h" |
10 | #include "util/header.h" | 10 | #include "util/header.h" |
11 | 11 | ||
12 | #include "util/parse-options.h" | 12 | #include <subcmd/parse-options.h> |
13 | #include "util/trace-event.h" | 13 | #include "util/trace-event.h" |
14 | 14 | ||
15 | #include "util/debug.h" | 15 | #include "util/debug.h" |
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 80170aace5d4..390170041696 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
@@ -1,7 +1,7 @@ | |||
1 | #include "builtin.h" | 1 | #include "builtin.h" |
2 | #include "perf.h" | 2 | #include "perf.h" |
3 | 3 | ||
4 | #include "util/parse-options.h" | 4 | #include <subcmd/parse-options.h> |
5 | #include "util/trace-event.h" | 5 | #include "util/trace-event.h" |
6 | #include "util/tool.h" | 6 | #include "util/tool.h" |
7 | #include "util/session.h" | 7 | #include "util/session.h" |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 132afc97676c..9af859b28b15 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "util/strfilter.h" | 37 | #include "util/strfilter.h" |
38 | #include "util/symbol.h" | 38 | #include "util/symbol.h" |
39 | #include "util/debug.h" | 39 | #include "util/debug.h" |
40 | #include "util/parse-options.h" | 40 | #include <subcmd/parse-options.h> |
41 | #include "util/probe-finder.h" | 41 | #include "util/probe-finder.h" |
42 | #include "util/probe-event.h" | 42 | #include "util/probe-event.h" |
43 | #include "util/probe-file.h" | 43 | #include "util/probe-file.h" |
@@ -249,6 +249,9 @@ static int opt_show_vars(const struct option *opt, | |||
249 | 249 | ||
250 | return ret; | 250 | return ret; |
251 | } | 251 | } |
252 | #else | ||
253 | # define opt_show_lines NULL | ||
254 | # define opt_show_vars NULL | ||
252 | #endif | 255 | #endif |
253 | static int opt_add_probe_event(const struct option *opt, | 256 | static int opt_add_probe_event(const struct option *opt, |
254 | const char *str, int unset __maybe_unused) | 257 | const char *str, int unset __maybe_unused) |
@@ -473,7 +476,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
473 | opt_add_probe_event), | 476 | opt_add_probe_event), |
474 | OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events" | 477 | OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events" |
475 | " with existing name"), | 478 | " with existing name"), |
476 | #ifdef HAVE_DWARF_SUPPORT | ||
477 | OPT_CALLBACK('L', "line", NULL, | 479 | OPT_CALLBACK('L', "line", NULL, |
478 | "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]", | 480 | "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]", |
479 | "Show source code lines.", opt_show_lines), | 481 | "Show source code lines.", opt_show_lines), |
@@ -490,7 +492,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
490 | "directory", "path to kernel source"), | 492 | "directory", "path to kernel source"), |
491 | OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, | 493 | OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, |
492 | "Don't search inlined functions"), | 494 | "Don't search inlined functions"), |
493 | #endif | ||
494 | OPT__DRY_RUN(&probe_event_dry_run), | 495 | OPT__DRY_RUN(&probe_event_dry_run), |
495 | OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes, | 496 | OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes, |
496 | "Set how many probe points can be found for a probe."), | 497 | "Set how many probe points can be found for a probe."), |
@@ -521,6 +522,16 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
521 | #ifdef HAVE_DWARF_SUPPORT | 522 | #ifdef HAVE_DWARF_SUPPORT |
522 | set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE); | 523 | set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE); |
523 | set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE); | 524 | set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE); |
525 | #else | ||
526 | # define set_nobuild(s, l, c) set_option_nobuild(options, s, l, "NO_DWARF=1", c) | ||
527 | set_nobuild('L', "line", false); | ||
528 | set_nobuild('V', "vars", false); | ||
529 | set_nobuild('\0', "externs", false); | ||
530 | set_nobuild('\0', "range", false); | ||
531 | set_nobuild('k', "vmlinux", true); | ||
532 | set_nobuild('s', "source", true); | ||
533 | set_nobuild('\0', "no-inlines", true); | ||
534 | # undef set_nobuild | ||
524 | #endif | 535 | #endif |
525 | set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE); | 536 | set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE); |
526 | 537 | ||
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 199fc31e3919..1435ef6265b6 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #include "util/build-id.h" | 12 | #include "util/build-id.h" |
13 | #include "util/util.h" | 13 | #include "util/util.h" |
14 | #include "util/parse-options.h" | 14 | #include <subcmd/parse-options.h> |
15 | #include "util/parse-events.h" | 15 | #include "util/parse-events.h" |
16 | 16 | ||
17 | #include "util/callchain.h" | 17 | #include "util/callchain.h" |
@@ -837,6 +837,19 @@ int record_callchain_opt(const struct option *opt, | |||
837 | 837 | ||
838 | static int perf_record_config(const char *var, const char *value, void *cb) | 838 | static int perf_record_config(const char *var, const char *value, void *cb) |
839 | { | 839 | { |
840 | struct record *rec = cb; | ||
841 | |||
842 | if (!strcmp(var, "record.build-id")) { | ||
843 | if (!strcmp(value, "cache")) | ||
844 | rec->no_buildid_cache = false; | ||
845 | else if (!strcmp(value, "no-cache")) | ||
846 | rec->no_buildid_cache = true; | ||
847 | else if (!strcmp(value, "skip")) | ||
848 | rec->no_buildid = true; | ||
849 | else | ||
850 | return -1; | ||
851 | return 0; | ||
852 | } | ||
840 | if (!strcmp(var, "record.call-graph")) | 853 | if (!strcmp(var, "record.call-graph")) |
841 | var = "call-graph.record-mode"; /* fall-through */ | 854 | var = "call-graph.record-mode"; /* fall-through */ |
842 | 855 | ||
@@ -1113,12 +1126,12 @@ struct option __record_options[] = { | |||
1113 | "per thread proc mmap processing timeout in ms"), | 1126 | "per thread proc mmap processing timeout in ms"), |
1114 | OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, | 1127 | OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, |
1115 | "Record context switch events"), | 1128 | "Record context switch events"), |
1116 | #ifdef HAVE_LIBBPF_SUPPORT | ||
1117 | OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", | 1129 | OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", |
1118 | "clang binary to use for compiling BPF scriptlets"), | 1130 | "clang binary to use for compiling BPF scriptlets"), |
1119 | OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", | 1131 | OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", |
1120 | "options passed to clang when compiling BPF scriptlets"), | 1132 | "options passed to clang when compiling BPF scriptlets"), |
1121 | #endif | 1133 | OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, |
1134 | "file", "vmlinux pathname"), | ||
1122 | OPT_END() | 1135 | OPT_END() |
1123 | }; | 1136 | }; |
1124 | 1137 | ||
@@ -1130,6 +1143,27 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1130 | struct record *rec = &record; | 1143 | struct record *rec = &record; |
1131 | char errbuf[BUFSIZ]; | 1144 | char errbuf[BUFSIZ]; |
1132 | 1145 | ||
1146 | #ifndef HAVE_LIBBPF_SUPPORT | ||
1147 | # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) | ||
1148 | set_nobuild('\0', "clang-path", true); | ||
1149 | set_nobuild('\0', "clang-opt", true); | ||
1150 | # undef set_nobuild | ||
1151 | #endif | ||
1152 | |||
1153 | #ifndef HAVE_BPF_PROLOGUE | ||
1154 | # if !defined (HAVE_DWARF_SUPPORT) | ||
1155 | # define REASON "NO_DWARF=1" | ||
1156 | # elif !defined (HAVE_LIBBPF_SUPPORT) | ||
1157 | # define REASON "NO_LIBBPF=1" | ||
1158 | # else | ||
1159 | # define REASON "this architecture doesn't support BPF prologue" | ||
1160 | # endif | ||
1161 | # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) | ||
1162 | set_nobuild('\0', "vmlinux", true); | ||
1163 | # undef set_nobuild | ||
1164 | # undef REASON | ||
1165 | #endif | ||
1166 | |||
1133 | rec->evlist = perf_evlist__new(); | 1167 | rec->evlist = perf_evlist__new(); |
1134 | if (rec->evlist == NULL) | 1168 | if (rec->evlist == NULL) |
1135 | return -ENOMEM; | 1169 | return -ENOMEM; |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5a454669d075..2a7330b99b82 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "util/session.h" | 27 | #include "util/session.h" |
28 | #include "util/tool.h" | 28 | #include "util/tool.h" |
29 | 29 | ||
30 | #include "util/parse-options.h" | 30 | #include <subcmd/parse-options.h> |
31 | #include "util/parse-events.h" | 31 | #include "util/parse-events.h" |
32 | 32 | ||
33 | #include "util/thread.h" | 33 | #include "util/thread.h" |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index e3d3e32c0a93..871b55ae22a4 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "util/tool.h" | 12 | #include "util/tool.h" |
13 | #include "util/cloexec.h" | 13 | #include "util/cloexec.h" |
14 | 14 | ||
15 | #include "util/parse-options.h" | 15 | #include <subcmd/parse-options.h> |
16 | #include "util/trace-event.h" | 16 | #include "util/trace-event.h" |
17 | 17 | ||
18 | #include "util/debug.h" | 18 | #include "util/debug.h" |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d259e9aa3a71..bcc3542d9df5 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -3,9 +3,9 @@ | |||
3 | #include "perf.h" | 3 | #include "perf.h" |
4 | #include "util/cache.h" | 4 | #include "util/cache.h" |
5 | #include "util/debug.h" | 5 | #include "util/debug.h" |
6 | #include "util/exec_cmd.h" | 6 | #include <subcmd/exec-cmd.h> |
7 | #include "util/header.h" | 7 | #include "util/header.h" |
8 | #include "util/parse-options.h" | 8 | #include <subcmd/parse-options.h> |
9 | #include "util/perf_regs.h" | 9 | #include "util/perf_regs.h" |
10 | #include "util/session.h" | 10 | #include "util/session.h" |
11 | #include "util/tool.h" | 11 | #include "util/tool.h" |
@@ -1408,7 +1408,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused, | |||
1408 | char first_half[BUFSIZ]; | 1408 | char first_half[BUFSIZ]; |
1409 | char *script_root; | 1409 | char *script_root; |
1410 | 1410 | ||
1411 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); | 1411 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); |
1412 | 1412 | ||
1413 | scripts_dir = opendir(scripts_path); | 1413 | scripts_dir = opendir(scripts_path); |
1414 | if (!scripts_dir) | 1414 | if (!scripts_dir) |
@@ -1529,7 +1529,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array) | |||
1529 | if (!session) | 1529 | if (!session) |
1530 | return -1; | 1530 | return -1; |
1531 | 1531 | ||
1532 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); | 1532 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); |
1533 | 1533 | ||
1534 | scripts_dir = opendir(scripts_path); | 1534 | scripts_dir = opendir(scripts_path); |
1535 | if (!scripts_dir) { | 1535 | if (!scripts_dir) { |
@@ -1587,7 +1587,7 @@ static char *get_script_path(const char *script_root, const char *suffix) | |||
1587 | char lang_path[MAXPATHLEN]; | 1587 | char lang_path[MAXPATHLEN]; |
1588 | char *__script_root; | 1588 | char *__script_root; |
1589 | 1589 | ||
1590 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); | 1590 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); |
1591 | 1591 | ||
1592 | scripts_dir = opendir(scripts_path); | 1592 | scripts_dir = opendir(scripts_path); |
1593 | if (!scripts_dir) | 1593 | if (!scripts_dir) |
@@ -1823,7 +1823,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1823 | scripting_max_stack = itrace_synth_opts.callchain_sz; | 1823 | scripting_max_stack = itrace_synth_opts.callchain_sz; |
1824 | 1824 | ||
1825 | /* make sure PERF_EXEC_PATH is set for scripts */ | 1825 | /* make sure PERF_EXEC_PATH is set for scripts */ |
1826 | perf_set_argv_exec_path(perf_exec_path()); | 1826 | set_argv_exec_path(get_argv_exec_path()); |
1827 | 1827 | ||
1828 | if (argc && !script_name && !rec_script_path && !rep_script_path) { | 1828 | if (argc && !script_name && !rec_script_path && !rep_script_path) { |
1829 | int live_pipe[2]; | 1829 | int live_pipe[2]; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 25a95f49c36e..bbf42eefd5e5 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "builtin.h" | 45 | #include "builtin.h" |
46 | #include "util/cgroup.h" | 46 | #include "util/cgroup.h" |
47 | #include "util/util.h" | 47 | #include "util/util.h" |
48 | #include "util/parse-options.h" | 48 | #include <subcmd/parse-options.h> |
49 | #include "util/parse-events.h" | 49 | #include "util/parse-events.h" |
50 | #include "util/pmu.h" | 50 | #include "util/pmu.h" |
51 | #include "util/event.h" | 51 | #include "util/event.h" |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 30e59620179d..bd7a7757176f 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #include "perf.h" | 31 | #include "perf.h" |
32 | #include "util/header.h" | 32 | #include "util/header.h" |
33 | #include "util/parse-options.h" | 33 | #include <subcmd/parse-options.h> |
34 | #include "util/parse-events.h" | 34 | #include "util/parse-events.h" |
35 | #include "util/event.h" | 35 | #include "util/event.h" |
36 | #include "util/session.h" | 36 | #include "util/session.h" |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 92fe963e43c4..9ebd67a42ede 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "util/top.h" | 34 | #include "util/top.h" |
35 | #include "util/util.h" | 35 | #include "util/util.h" |
36 | #include <linux/rbtree.h> | 36 | #include <linux/rbtree.h> |
37 | #include "util/parse-options.h" | 37 | #include <subcmd/parse-options.h> |
38 | #include "util/parse-events.h" | 38 | #include "util/parse-events.h" |
39 | #include "util/cpumap.h" | 39 | #include "util/cpumap.h" |
40 | #include "util/xyarray.h" | 40 | #include "util/xyarray.h" |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c783d8fd3a80..20916dd77aac 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -22,11 +22,11 @@ | |||
22 | #include "util/color.h" | 22 | #include "util/color.h" |
23 | #include "util/debug.h" | 23 | #include "util/debug.h" |
24 | #include "util/evlist.h" | 24 | #include "util/evlist.h" |
25 | #include "util/exec_cmd.h" | 25 | #include <subcmd/exec-cmd.h> |
26 | #include "util/machine.h" | 26 | #include "util/machine.h" |
27 | #include "util/session.h" | 27 | #include "util/session.h" |
28 | #include "util/thread.h" | 28 | #include "util/thread.h" |
29 | #include "util/parse-options.h" | 29 | #include <subcmd/parse-options.h> |
30 | #include "util/strlist.h" | 30 | #include "util/strlist.h" |
31 | #include "util/intlist.h" | 31 | #include "util/intlist.h" |
32 | #include "util/thread_map.h" | 32 | #include "util/thread_map.h" |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 59ea48c7e26c..cb1d2499c45c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
@@ -9,12 +9,12 @@ | |||
9 | #include "builtin.h" | 9 | #include "builtin.h" |
10 | 10 | ||
11 | #include "util/env.h" | 11 | #include "util/env.h" |
12 | #include "util/exec_cmd.h" | 12 | #include <subcmd/exec-cmd.h> |
13 | #include "util/cache.h" | 13 | #include "util/cache.h" |
14 | #include "util/quote.h" | 14 | #include "util/quote.h" |
15 | #include "util/run-command.h" | 15 | #include <subcmd/run-command.h> |
16 | #include "util/parse-events.h" | 16 | #include "util/parse-events.h" |
17 | #include "util/parse-options.h" | 17 | #include <subcmd/parse-options.h> |
18 | #include "util/bpf-loader.h" | 18 | #include "util/bpf-loader.h" |
19 | #include "util/debug.h" | 19 | #include "util/debug.h" |
20 | #include <api/fs/tracing_path.h> | 20 | #include <api/fs/tracing_path.h> |
@@ -119,7 +119,7 @@ static void commit_pager_choice(void) | |||
119 | { | 119 | { |
120 | switch (use_pager) { | 120 | switch (use_pager) { |
121 | case 0: | 121 | case 0: |
122 | setenv("PERF_PAGER", "cat", 1); | 122 | setenv(PERF_PAGER_ENVIRONMENT, "cat", 1); |
123 | break; | 123 | break; |
124 | case 1: | 124 | case 1: |
125 | /* setup_pager(); */ | 125 | /* setup_pager(); */ |
@@ -183,9 +183,9 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) | |||
183 | if (!prefixcmp(cmd, CMD_EXEC_PATH)) { | 183 | if (!prefixcmp(cmd, CMD_EXEC_PATH)) { |
184 | cmd += strlen(CMD_EXEC_PATH); | 184 | cmd += strlen(CMD_EXEC_PATH); |
185 | if (*cmd == '=') | 185 | if (*cmd == '=') |
186 | perf_set_argv_exec_path(cmd + 1); | 186 | set_argv_exec_path(cmd + 1); |
187 | else { | 187 | else { |
188 | puts(perf_exec_path()); | 188 | puts(get_argv_exec_path()); |
189 | exit(0); | 189 | exit(0); |
190 | } | 190 | } |
191 | } else if (!strcmp(cmd, "--html-path")) { | 191 | } else if (!strcmp(cmd, "--html-path")) { |
@@ -530,11 +530,15 @@ int main(int argc, const char **argv) | |||
530 | const char *cmd; | 530 | const char *cmd; |
531 | char sbuf[STRERR_BUFSIZE]; | 531 | char sbuf[STRERR_BUFSIZE]; |
532 | 532 | ||
533 | /* libsubcmd init */ | ||
534 | exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT); | ||
535 | pager_init(PERF_PAGER_ENVIRONMENT); | ||
536 | |||
533 | /* The page_size is placed in util object. */ | 537 | /* The page_size is placed in util object. */ |
534 | page_size = sysconf(_SC_PAGE_SIZE); | 538 | page_size = sysconf(_SC_PAGE_SIZE); |
535 | cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); | 539 | cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); |
536 | 540 | ||
537 | cmd = perf_extract_argv0_path(argv[0]); | 541 | cmd = extract_argv0_path(argv[0]); |
538 | if (!cmd) | 542 | if (!cmd) |
539 | cmd = "perf-help"; | 543 | cmd = "perf-help"; |
540 | 544 | ||
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 0ff8a973b81c..f23fb7ed4400 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build | |||
@@ -35,21 +35,21 @@ perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o | |||
35 | perf-y += bpf.o | 35 | perf-y += bpf.o |
36 | perf-y += topology.o | 36 | perf-y += topology.o |
37 | 37 | ||
38 | $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c | 38 | $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build |
39 | $(call rule_mkdir) | 39 | $(call rule_mkdir) |
40 | $(Q)echo '#include <tests/llvm.h>' > $@ | 40 | $(Q)echo '#include <tests/llvm.h>' > $@ |
41 | $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@ | 41 | $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@ |
42 | $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ | 42 | $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ |
43 | $(Q)echo ';' >> $@ | 43 | $(Q)echo ';' >> $@ |
44 | 44 | ||
45 | $(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c | 45 | $(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build |
46 | $(call rule_mkdir) | 46 | $(call rule_mkdir) |
47 | $(Q)echo '#include <tests/llvm.h>' > $@ | 47 | $(Q)echo '#include <tests/llvm.h>' > $@ |
48 | $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@ | 48 | $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@ |
49 | $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ | 49 | $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ |
50 | $(Q)echo ';' >> $@ | 50 | $(Q)echo ';' >> $@ |
51 | 51 | ||
52 | $(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c | 52 | $(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c tests/Build |
53 | $(call rule_mkdir) | 53 | $(call rule_mkdir) |
54 | $(Q)echo '#include <tests/llvm.h>' > $@ | 54 | $(Q)echo '#include <tests/llvm.h>' > $@ |
55 | $(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@ | 55 | $(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@ |
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index b66730eb94e3..28d1605b0338 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include "../perf.h" | 25 | #include "../perf.h" |
26 | #include "util.h" | 26 | #include "util.h" |
27 | #include "exec_cmd.h" | 27 | #include <subcmd/exec-cmd.h> |
28 | #include "tests.h" | 28 | #include "tests.h" |
29 | 29 | ||
30 | #define ENV "PERF_TEST_ATTR" | 30 | #define ENV "PERF_TEST_ATTR" |
@@ -164,7 +164,7 @@ int test__attr(int subtest __maybe_unused) | |||
164 | return run_dir("./tests", "./perf"); | 164 | return run_dir("./tests", "./perf"); |
165 | 165 | ||
166 | /* Then installed path. */ | 166 | /* Then installed path. */ |
167 | snprintf(path_dir, PATH_MAX, "%s/tests", perf_exec_path()); | 167 | snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path()); |
168 | snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR); | 168 | snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR); |
169 | 169 | ||
170 | if (!lstat(path_dir, &st) && | 170 | if (!lstat(path_dir, &st) && |
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 2b1ade1aafc3..0372d5945910 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include "tests.h" | 11 | #include "tests.h" |
12 | #include "debug.h" | 12 | #include "debug.h" |
13 | #include "color.h" | 13 | #include "color.h" |
14 | #include "parse-options.h" | 14 | #include <subcmd/parse-options.h> |
15 | #include "symbol.h" | 15 | #include "symbol.h" |
16 | 16 | ||
17 | struct test __weak arch_tests[] = { | 17 | struct test __weak arch_tests[] = { |
@@ -236,6 +236,9 @@ static int run_test(struct test *test, int subtest) | |||
236 | dup2(STDOUT_FILENO, STDERR_FILENO); | 236 | dup2(STDOUT_FILENO, STDERR_FILENO); |
237 | close(nullfd); | 237 | close(nullfd); |
238 | } | 238 | } |
239 | } else { | ||
240 | signal(SIGSEGV, sighandler_dump_stack); | ||
241 | signal(SIGFPE, sighandler_dump_stack); | ||
239 | } | 242 | } |
240 | 243 | ||
241 | err = test->func(subtest); | 244 | err = test->func(subtest); |
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 46f453b1de60..bcfd081ee1d2 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c | |||
@@ -88,8 +88,8 @@ struct machine *setup_fake_machine(struct machines *machines) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | if (machine__create_kernel_maps(machine)) { | 90 | if (machine__create_kernel_maps(machine)) { |
91 | pr_debug("Not enough memory for machine setup\n"); | 91 | pr_debug("Cannot create kernel maps\n"); |
92 | goto out; | 92 | return NULL; |
93 | } | 93 | } |
94 | 94 | ||
95 | for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { | 95 | for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { |
@@ -155,7 +155,6 @@ struct machine *setup_fake_machine(struct machines *machines) | |||
155 | out: | 155 | out: |
156 | pr_debug("Not enough memory for machine setup\n"); | 156 | pr_debug("Not enough memory for machine setup\n"); |
157 | machine__delete_threads(machine); | 157 | machine__delete_threads(machine); |
158 | machine__delete(machine); | ||
159 | return NULL; | 158 | return NULL; |
160 | } | 159 | } |
161 | 160 | ||
diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 8ea3dffc5065..c1fbb8e884c0 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make | |||
@@ -259,7 +259,8 @@ $(run_O): | |||
259 | tarpkg: | 259 | tarpkg: |
260 | @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \ | 260 | @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \ |
261 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ | 261 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ |
262 | ( eval $$cmd ) >> $@ 2>&1 | 262 | ( eval $$cmd ) >> $@ 2>&1 && \ |
263 | rm -f $@ | ||
263 | 264 | ||
264 | make_kernelsrc: | 265 | make_kernelsrc: |
265 | @echo "- make -C <kernelsrc> tools/perf" | 266 | @echo "- make -C <kernelsrc> tools/perf" |
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 65fef5951c7d..94b1099f2c22 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build | |||
@@ -9,13 +9,10 @@ libperf-y += env.o | |||
9 | libperf-y += event.o | 9 | libperf-y += event.o |
10 | libperf-y += evlist.o | 10 | libperf-y += evlist.o |
11 | libperf-y += evsel.o | 11 | libperf-y += evsel.o |
12 | libperf-y += exec_cmd.o | ||
13 | libperf-y += find_next_bit.o | 12 | libperf-y += find_next_bit.o |
14 | libperf-y += help.o | ||
15 | libperf-y += kallsyms.o | 13 | libperf-y += kallsyms.o |
16 | libperf-y += levenshtein.o | 14 | libperf-y += levenshtein.o |
17 | libperf-y += llvm-utils.o | 15 | libperf-y += llvm-utils.o |
18 | libperf-y += parse-options.o | ||
19 | libperf-y += parse-events.o | 16 | libperf-y += parse-events.o |
20 | libperf-y += perf_regs.o | 17 | libperf-y += perf_regs.o |
21 | libperf-y += path.o | 18 | libperf-y += path.o |
@@ -23,7 +20,6 @@ libperf-y += rbtree.o | |||
23 | libperf-y += libstring.o | 20 | libperf-y += libstring.o |
24 | libperf-y += bitmap.o | 21 | libperf-y += bitmap.o |
25 | libperf-y += hweight.o | 22 | libperf-y += hweight.o |
26 | libperf-y += run-command.o | ||
27 | libperf-y += quote.o | 23 | libperf-y += quote.o |
28 | libperf-y += strbuf.o | 24 | libperf-y += strbuf.o |
29 | libperf-y += string.o | 25 | libperf-y += string.o |
@@ -32,11 +28,9 @@ libperf-y += strfilter.o | |||
32 | libperf-y += top.o | 28 | libperf-y += top.o |
33 | libperf-y += usage.o | 29 | libperf-y += usage.o |
34 | libperf-y += wrapper.o | 30 | libperf-y += wrapper.o |
35 | libperf-y += sigchain.o | ||
36 | libperf-y += dso.o | 31 | libperf-y += dso.o |
37 | libperf-y += symbol.o | 32 | libperf-y += symbol.o |
38 | libperf-y += color.o | 33 | libperf-y += color.o |
39 | libperf-y += pager.o | ||
40 | libperf-y += header.o | 34 | libperf-y += header.o |
41 | libperf-y += callchain.o | 35 | libperf-y += callchain.o |
42 | libperf-y += values.o | 36 | libperf-y += values.o |
@@ -87,6 +81,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-bts.o | |||
87 | libperf-y += parse-branch-options.o | 81 | libperf-y += parse-branch-options.o |
88 | libperf-y += parse-regs-options.o | 82 | libperf-y += parse-regs-options.o |
89 | libperf-y += term.o | 83 | libperf-y += term.o |
84 | libperf-y += help-unknown-cmd.o | ||
90 | 85 | ||
91 | libperf-$(CONFIG_LIBBPF) += bpf-loader.o | 86 | libperf-$(CONFIG_LIBBPF) += bpf-loader.o |
92 | libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o | 87 | libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o |
@@ -112,7 +107,6 @@ libperf-$(CONFIG_ZLIB) += zlib.o | |||
112 | libperf-$(CONFIG_LZMA) += lzma.o | 107 | libperf-$(CONFIG_LZMA) += lzma.o |
113 | 108 | ||
114 | CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" | 109 | CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" |
115 | CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" | ||
116 | 110 | ||
117 | $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c | 111 | $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c |
118 | $(call rule_mkdir) | 112 | $(call rule_mkdir) |
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 7f10430af39c..360fda01f3b0 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "event.h" | 45 | #include "event.h" |
46 | #include "session.h" | 46 | #include "session.h" |
47 | #include "debug.h" | 47 | #include "debug.h" |
48 | #include "parse-options.h" | 48 | #include <subcmd/parse-options.h> |
49 | 49 | ||
50 | #include "intel-pt.h" | 50 | #include "intel-pt.h" |
51 | #include "intel-bts.h" | 51 | #include "intel-bts.h" |
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 4c2b76499dd5..07b5d63947b1 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -4,9 +4,12 @@ | |||
4 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | #include "util.h" | 5 | #include "util.h" |
6 | #include "strbuf.h" | 6 | #include "strbuf.h" |
7 | #include <subcmd/pager.h> | ||
7 | #include "../perf.h" | 8 | #include "../perf.h" |
8 | #include "../ui/ui.h" | 9 | #include "../ui/ui.h" |
9 | 10 | ||
11 | #include <linux/string.h> | ||
12 | |||
10 | #define CMD_EXEC_PATH "--exec-path" | 13 | #define CMD_EXEC_PATH "--exec-path" |
11 | #define CMD_PERF_DIR "--perf-dir=" | 14 | #define CMD_PERF_DIR "--perf-dir=" |
12 | #define CMD_WORK_TREE "--work-tree=" | 15 | #define CMD_WORK_TREE "--work-tree=" |
@@ -18,6 +21,7 @@ | |||
18 | #define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" | 21 | #define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" |
19 | #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" | 22 | #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" |
20 | #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" | 23 | #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" |
24 | #define PERF_PAGER_ENVIRONMENT "PERF_PAGER" | ||
21 | 25 | ||
22 | typedef int (*config_fn_t)(const char *, const char *, void *); | 26 | typedef int (*config_fn_t)(const char *, const char *, void *); |
23 | extern int perf_default_config(const char *, const char *, void *); | 27 | extern int perf_default_config(const char *, const char *, void *); |
@@ -28,10 +32,6 @@ extern int perf_config_bool(const char *, const char *); | |||
28 | extern int config_error_nonbool(const char *); | 32 | extern int config_error_nonbool(const char *); |
29 | extern const char *perf_config_dirname(const char *, const char *); | 33 | extern const char *perf_config_dirname(const char *, const char *); |
30 | 34 | ||
31 | /* pager.c */ | ||
32 | extern void setup_pager(void); | ||
33 | extern int pager_in_use(void); | ||
34 | |||
35 | char *alias_lookup(const char *alias); | 35 | char *alias_lookup(const char *alias); |
36 | int split_cmdline(char *cmdline, const char ***argv); | 36 | int split_cmdline(char *cmdline, const char ***argv); |
37 | 37 | ||
@@ -70,9 +70,4 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2 | |||
70 | extern char *perf_pathdup(const char *fmt, ...) | 70 | extern char *perf_pathdup(const char *fmt, ...) |
71 | __attribute__((format (printf, 1, 2))); | 71 | __attribute__((format (printf, 1, 2))); |
72 | 72 | ||
73 | #ifndef __UCLIBC__ | ||
74 | /* Matches the libc/libbsd function attribute so we declare this unconditionally: */ | ||
75 | extern size_t strlcpy(char *dest, const char *src, size_t size); | ||
76 | #endif | ||
77 | |||
78 | #endif /* __PERF_CACHE_H */ | 73 | #endif /* __PERF_CACHE_H */ |
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 32e12ecfe9c5..90aa1b46b2e5 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include "util.h" | 1 | #include "util.h" |
2 | #include "../perf.h" | 2 | #include "../perf.h" |
3 | #include "parse-options.h" | 3 | #include <subcmd/parse-options.h> |
4 | #include "evsel.h" | 4 | #include "evsel.h" |
5 | #include "cgroup.h" | 5 | #include "cgroup.h" |
6 | #include "evlist.h" | 6 | #include "evlist.h" |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 2e452ac1353d..d3e12e30e1d5 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | #include "util.h" | 11 | #include "util.h" |
12 | #include "cache.h" | 12 | #include "cache.h" |
13 | #include "exec_cmd.h" | 13 | #include <subcmd/exec-cmd.h> |
14 | #include "util/hist.h" /* perf_hist_config */ | 14 | #include "util/hist.h" /* perf_hist_config */ |
15 | #include "util/llvm-utils.h" /* perf_llvm_config */ | 15 | #include "util/llvm-utils.h" /* perf_llvm_config */ |
16 | 16 | ||
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d1b6c206bb93..8c44aadb9810 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <unistd.h> | 18 | #include <unistd.h> |
19 | 19 | ||
20 | #include "parse-events.h" | 20 | #include "parse-events.h" |
21 | #include "parse-options.h" | 21 | #include <subcmd/parse-options.h> |
22 | 22 | ||
23 | #include <sys/mman.h> | 23 | #include <sys/mman.h> |
24 | 24 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 47f033089349..544e4400de13 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -36,6 +36,7 @@ static struct { | |||
36 | bool cloexec; | 36 | bool cloexec; |
37 | bool clockid; | 37 | bool clockid; |
38 | bool clockid_wrong; | 38 | bool clockid_wrong; |
39 | bool lbr_flags; | ||
39 | } perf_missing_features; | 40 | } perf_missing_features; |
40 | 41 | ||
41 | static clockid_t clockid; | 42 | static clockid_t clockid; |
@@ -574,7 +575,9 @@ perf_evsel__config_callgraph(struct perf_evsel *evsel, | |||
574 | } else { | 575 | } else { |
575 | perf_evsel__set_sample_bit(evsel, BRANCH_STACK); | 576 | perf_evsel__set_sample_bit(evsel, BRANCH_STACK); |
576 | attr->branch_sample_type = PERF_SAMPLE_BRANCH_USER | | 577 | attr->branch_sample_type = PERF_SAMPLE_BRANCH_USER | |
577 | PERF_SAMPLE_BRANCH_CALL_STACK; | 578 | PERF_SAMPLE_BRANCH_CALL_STACK | |
579 | PERF_SAMPLE_BRANCH_NO_CYCLES | | ||
580 | PERF_SAMPLE_BRANCH_NO_FLAGS; | ||
578 | } | 581 | } |
579 | } else | 582 | } else |
580 | pr_warning("Cannot use LBR callstack with branch stack. " | 583 | pr_warning("Cannot use LBR callstack with branch stack. " |
@@ -1337,6 +1340,9 @@ fallback_missing_features: | |||
1337 | evsel->attr.mmap2 = 0; | 1340 | evsel->attr.mmap2 = 0; |
1338 | if (perf_missing_features.exclude_guest) | 1341 | if (perf_missing_features.exclude_guest) |
1339 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; | 1342 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; |
1343 | if (perf_missing_features.lbr_flags) | ||
1344 | evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | | ||
1345 | PERF_SAMPLE_BRANCH_NO_CYCLES); | ||
1340 | retry_sample_id: | 1346 | retry_sample_id: |
1341 | if (perf_missing_features.sample_id_all) | 1347 | if (perf_missing_features.sample_id_all) |
1342 | evsel->attr.sample_id_all = 0; | 1348 | evsel->attr.sample_id_all = 0; |
@@ -1455,6 +1461,12 @@ try_fallback: | |||
1455 | } else if (!perf_missing_features.sample_id_all) { | 1461 | } else if (!perf_missing_features.sample_id_all) { |
1456 | perf_missing_features.sample_id_all = true; | 1462 | perf_missing_features.sample_id_all = true; |
1457 | goto retry_sample_id; | 1463 | goto retry_sample_id; |
1464 | } else if (!perf_missing_features.lbr_flags && | ||
1465 | (evsel->attr.branch_sample_type & | ||
1466 | (PERF_SAMPLE_BRANCH_NO_CYCLES | | ||
1467 | PERF_SAMPLE_BRANCH_NO_FLAGS))) { | ||
1468 | perf_missing_features.lbr_flags = true; | ||
1469 | goto fallback_missing_features; | ||
1458 | } | 1470 | } |
1459 | 1471 | ||
1460 | out_close: | 1472 | out_close: |
diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c deleted file mode 100644 index 1099e92f5ee1..000000000000 --- a/tools/perf/util/exec_cmd.c +++ /dev/null | |||
@@ -1,149 +0,0 @@ | |||
1 | #include "cache.h" | ||
2 | #include "exec_cmd.h" | ||
3 | #include "quote.h" | ||
4 | |||
5 | #include <string.h> | ||
6 | |||
7 | #define MAX_ARGS 32 | ||
8 | |||
9 | static const char *argv_exec_path; | ||
10 | static const char *argv0_path; | ||
11 | |||
12 | char *system_path(const char *path) | ||
13 | { | ||
14 | static const char *prefix = PREFIX; | ||
15 | struct strbuf d = STRBUF_INIT; | ||
16 | |||
17 | if (is_absolute_path(path)) | ||
18 | return strdup(path); | ||
19 | |||
20 | strbuf_addf(&d, "%s/%s", prefix, path); | ||
21 | path = strbuf_detach(&d, NULL); | ||
22 | return (char *)path; | ||
23 | } | ||
24 | |||
25 | const char *perf_extract_argv0_path(const char *argv0) | ||
26 | { | ||
27 | const char *slash; | ||
28 | |||
29 | if (!argv0 || !*argv0) | ||
30 | return NULL; | ||
31 | slash = argv0 + strlen(argv0); | ||
32 | |||
33 | while (argv0 <= slash && !is_dir_sep(*slash)) | ||
34 | slash--; | ||
35 | |||
36 | if (slash >= argv0) { | ||
37 | argv0_path = strndup(argv0, slash - argv0); | ||
38 | return argv0_path ? slash + 1 : NULL; | ||
39 | } | ||
40 | |||
41 | return argv0; | ||
42 | } | ||
43 | |||
44 | void perf_set_argv_exec_path(const char *exec_path) | ||
45 | { | ||
46 | argv_exec_path = exec_path; | ||
47 | /* | ||
48 | * Propagate this setting to external programs. | ||
49 | */ | ||
50 | setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1); | ||
51 | } | ||
52 | |||
53 | |||
54 | /* Returns the highest-priority, location to look for perf programs. */ | ||
55 | char *perf_exec_path(void) | ||
56 | { | ||
57 | char *env; | ||
58 | |||
59 | if (argv_exec_path) | ||
60 | return strdup(argv_exec_path); | ||
61 | |||
62 | env = getenv(EXEC_PATH_ENVIRONMENT); | ||
63 | if (env && *env) | ||
64 | return strdup(env); | ||
65 | |||
66 | return system_path(PERF_EXEC_PATH); | ||
67 | } | ||
68 | |||
69 | static void add_path(struct strbuf *out, const char *path) | ||
70 | { | ||
71 | if (path && *path) { | ||
72 | if (is_absolute_path(path)) | ||
73 | strbuf_addstr(out, path); | ||
74 | else | ||
75 | strbuf_addstr(out, make_nonrelative_path(path)); | ||
76 | |||
77 | strbuf_addch(out, PATH_SEP); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | void setup_path(void) | ||
82 | { | ||
83 | const char *old_path = getenv("PATH"); | ||
84 | struct strbuf new_path = STRBUF_INIT; | ||
85 | char *tmp = perf_exec_path(); | ||
86 | |||
87 | add_path(&new_path, tmp); | ||
88 | add_path(&new_path, argv0_path); | ||
89 | free(tmp); | ||
90 | |||
91 | if (old_path) | ||
92 | strbuf_addstr(&new_path, old_path); | ||
93 | else | ||
94 | strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin"); | ||
95 | |||
96 | setenv("PATH", new_path.buf, 1); | ||
97 | |||
98 | strbuf_release(&new_path); | ||
99 | } | ||
100 | |||
101 | static const char **prepare_perf_cmd(const char **argv) | ||
102 | { | ||
103 | int argc; | ||
104 | const char **nargv; | ||
105 | |||
106 | for (argc = 0; argv[argc]; argc++) | ||
107 | ; /* just counting */ | ||
108 | nargv = malloc(sizeof(*nargv) * (argc + 2)); | ||
109 | |||
110 | nargv[0] = "perf"; | ||
111 | for (argc = 0; argv[argc]; argc++) | ||
112 | nargv[argc + 1] = argv[argc]; | ||
113 | nargv[argc + 1] = NULL; | ||
114 | return nargv; | ||
115 | } | ||
116 | |||
117 | int execv_perf_cmd(const char **argv) { | ||
118 | const char **nargv = prepare_perf_cmd(argv); | ||
119 | |||
120 | /* execvp() can only ever return if it fails */ | ||
121 | execvp("perf", (char **)nargv); | ||
122 | |||
123 | free(nargv); | ||
124 | return -1; | ||
125 | } | ||
126 | |||
127 | |||
128 | int execl_perf_cmd(const char *cmd,...) | ||
129 | { | ||
130 | int argc; | ||
131 | const char *argv[MAX_ARGS + 1]; | ||
132 | const char *arg; | ||
133 | va_list param; | ||
134 | |||
135 | va_start(param, cmd); | ||
136 | argv[0] = cmd; | ||
137 | argc = 1; | ||
138 | while (argc < MAX_ARGS) { | ||
139 | arg = argv[argc++] = va_arg(param, char *); | ||
140 | if (!arg) | ||
141 | break; | ||
142 | } | ||
143 | va_end(param); | ||
144 | if (MAX_ARGS <= argc) | ||
145 | return error("too many args to run %s", cmd); | ||
146 | |||
147 | argv[argc] = NULL; | ||
148 | return execv_perf_cmd(argv); | ||
149 | } | ||
diff --git a/tools/perf/util/exec_cmd.h b/tools/perf/util/exec_cmd.h deleted file mode 100644 index 48b4175f1e11..000000000000 --- a/tools/perf/util/exec_cmd.h +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | #ifndef __PERF_EXEC_CMD_H | ||
2 | #define __PERF_EXEC_CMD_H | ||
3 | |||
4 | extern void perf_set_argv_exec_path(const char *exec_path); | ||
5 | extern const char *perf_extract_argv0_path(const char *path); | ||
6 | extern void setup_path(void); | ||
7 | extern int execv_perf_cmd(const char **argv); /* NULL terminated */ | ||
8 | extern int execl_perf_cmd(const char *cmd, ...); | ||
9 | /* perf_exec_path and system_path return malloc'd string, caller must free it */ | ||
10 | extern char *perf_exec_path(void); | ||
11 | extern char *system_path(const char *path); | ||
12 | |||
13 | #endif /* __PERF_EXEC_CMD_H */ | ||
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c new file mode 100644 index 000000000000..dc1e41c9b054 --- /dev/null +++ b/tools/perf/util/help-unknown-cmd.c | |||
@@ -0,0 +1,103 @@ | |||
1 | #include "cache.h" | ||
2 | #include <subcmd/help.h> | ||
3 | #include "../builtin.h" | ||
4 | #include "levenshtein.h" | ||
5 | |||
6 | static int autocorrect; | ||
7 | static struct cmdnames aliases; | ||
8 | |||
9 | static int perf_unknown_cmd_config(const char *var, const char *value, void *cb) | ||
10 | { | ||
11 | if (!strcmp(var, "help.autocorrect")) | ||
12 | autocorrect = perf_config_int(var,value); | ||
13 | /* Also use aliases for command lookup */ | ||
14 | if (!prefixcmp(var, "alias.")) | ||
15 | add_cmdname(&aliases, var + 6, strlen(var + 6)); | ||
16 | |||
17 | return perf_default_config(var, value, cb); | ||
18 | } | ||
19 | |||
20 | static int levenshtein_compare(const void *p1, const void *p2) | ||
21 | { | ||
22 | const struct cmdname *const *c1 = p1, *const *c2 = p2; | ||
23 | const char *s1 = (*c1)->name, *s2 = (*c2)->name; | ||
24 | int l1 = (*c1)->len; | ||
25 | int l2 = (*c2)->len; | ||
26 | return l1 != l2 ? l1 - l2 : strcmp(s1, s2); | ||
27 | } | ||
28 | |||
29 | static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) | ||
30 | { | ||
31 | unsigned int i; | ||
32 | |||
33 | ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); | ||
34 | |||
35 | for (i = 0; i < old->cnt; i++) | ||
36 | cmds->names[cmds->cnt++] = old->names[i]; | ||
37 | zfree(&old->names); | ||
38 | old->cnt = 0; | ||
39 | } | ||
40 | |||
41 | const char *help_unknown_cmd(const char *cmd) | ||
42 | { | ||
43 | unsigned int i, n = 0, best_similarity = 0; | ||
44 | struct cmdnames main_cmds, other_cmds; | ||
45 | |||
46 | memset(&main_cmds, 0, sizeof(main_cmds)); | ||
47 | memset(&other_cmds, 0, sizeof(main_cmds)); | ||
48 | memset(&aliases, 0, sizeof(aliases)); | ||
49 | |||
50 | perf_config(perf_unknown_cmd_config, NULL); | ||
51 | |||
52 | load_command_list("perf-", &main_cmds, &other_cmds); | ||
53 | |||
54 | add_cmd_list(&main_cmds, &aliases); | ||
55 | add_cmd_list(&main_cmds, &other_cmds); | ||
56 | qsort(main_cmds.names, main_cmds.cnt, | ||
57 | sizeof(main_cmds.names), cmdname_compare); | ||
58 | uniq(&main_cmds); | ||
59 | |||
60 | if (main_cmds.cnt) { | ||
61 | /* This reuses cmdname->len for similarity index */ | ||
62 | for (i = 0; i < main_cmds.cnt; ++i) | ||
63 | main_cmds.names[i]->len = | ||
64 | levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4); | ||
65 | |||
66 | qsort(main_cmds.names, main_cmds.cnt, | ||
67 | sizeof(*main_cmds.names), levenshtein_compare); | ||
68 | |||
69 | best_similarity = main_cmds.names[0]->len; | ||
70 | n = 1; | ||
71 | while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len) | ||
72 | ++n; | ||
73 | } | ||
74 | |||
75 | if (autocorrect && n == 1) { | ||
76 | const char *assumed = main_cmds.names[0]->name; | ||
77 | |||
78 | main_cmds.names[0] = NULL; | ||
79 | clean_cmdnames(&main_cmds); | ||
80 | fprintf(stderr, "WARNING: You called a perf program named '%s', " | ||
81 | "which does not exist.\n" | ||
82 | "Continuing under the assumption that you meant '%s'\n", | ||
83 | cmd, assumed); | ||
84 | if (autocorrect > 0) { | ||
85 | fprintf(stderr, "in %0.1f seconds automatically...\n", | ||
86 | (float)autocorrect/10.0); | ||
87 | poll(NULL, 0, autocorrect * 100); | ||
88 | } | ||
89 | return assumed; | ||
90 | } | ||
91 | |||
92 | fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd); | ||
93 | |||
94 | if (main_cmds.cnt && best_similarity < 6) { | ||
95 | fprintf(stderr, "\nDid you mean %s?\n", | ||
96 | n < 2 ? "this": "one of these"); | ||
97 | |||
98 | for (i = 0; i < n; i++) | ||
99 | fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); | ||
100 | } | ||
101 | |||
102 | exit(1); | ||
103 | } | ||
diff --git a/tools/perf/util/help-unknown-cmd.h b/tools/perf/util/help-unknown-cmd.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tools/perf/util/help-unknown-cmd.h | |||
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 97f963a3dcb9..81a2eb77ba7f 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -1744,7 +1744,7 @@ static void intel_pt_free(struct perf_session *session) | |||
1744 | auxtrace_heap__free(&pt->heap); | 1744 | auxtrace_heap__free(&pt->heap); |
1745 | intel_pt_free_events(session); | 1745 | intel_pt_free_events(session); |
1746 | session->auxtrace = NULL; | 1746 | session->auxtrace = NULL; |
1747 | thread__delete(pt->unknown_thread); | 1747 | thread__put(pt->unknown_thread); |
1748 | free(pt); | 1748 | free(pt); |
1749 | } | 1749 | } |
1750 | 1750 | ||
@@ -2153,7 +2153,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
2153 | return 0; | 2153 | return 0; |
2154 | 2154 | ||
2155 | err_delete_thread: | 2155 | err_delete_thread: |
2156 | thread__delete(pt->unknown_thread); | 2156 | thread__zput(pt->unknown_thread); |
2157 | err_free_queues: | 2157 | err_free_queues: |
2158 | intel_pt_log_disable(); | 2158 | intel_pt_log_disable(); |
2159 | auxtrace_queues__free(&pt->queues); | 2159 | auxtrace_queues__free(&pt->queues); |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 1407d5107480..ad79297c76c8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -352,13 +352,18 @@ static void machine__update_thread_pid(struct machine *machine, | |||
352 | } | 352 | } |
353 | 353 | ||
354 | th->mg = map_groups__get(leader->mg); | 354 | th->mg = map_groups__get(leader->mg); |
355 | 355 | out_put: | |
356 | thread__put(leader); | ||
356 | return; | 357 | return; |
357 | |||
358 | out_err: | 358 | out_err: |
359 | pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid); | 359 | pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid); |
360 | goto out_put; | ||
360 | } | 361 | } |
361 | 362 | ||
363 | /* | ||
364 | * Caller must eventually drop thread->refcnt returned with a successfull | ||
365 | * lookup/new thread inserted. | ||
366 | */ | ||
362 | static struct thread *____machine__findnew_thread(struct machine *machine, | 367 | static struct thread *____machine__findnew_thread(struct machine *machine, |
363 | pid_t pid, pid_t tid, | 368 | pid_t pid, pid_t tid, |
364 | bool create) | 369 | bool create) |
@@ -376,7 +381,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, | |||
376 | if (th != NULL) { | 381 | if (th != NULL) { |
377 | if (th->tid == tid) { | 382 | if (th->tid == tid) { |
378 | machine__update_thread_pid(machine, th, pid); | 383 | machine__update_thread_pid(machine, th, pid); |
379 | return th; | 384 | return thread__get(th); |
380 | } | 385 | } |
381 | 386 | ||
382 | machine->last_match = NULL; | 387 | machine->last_match = NULL; |
@@ -389,7 +394,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, | |||
389 | if (th->tid == tid) { | 394 | if (th->tid == tid) { |
390 | machine->last_match = th; | 395 | machine->last_match = th; |
391 | machine__update_thread_pid(machine, th, pid); | 396 | machine__update_thread_pid(machine, th, pid); |
392 | return th; | 397 | return thread__get(th); |
393 | } | 398 | } |
394 | 399 | ||
395 | if (tid < th->tid) | 400 | if (tid < th->tid) |
@@ -417,7 +422,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, | |||
417 | if (thread__init_map_groups(th, machine)) { | 422 | if (thread__init_map_groups(th, machine)) { |
418 | rb_erase_init(&th->rb_node, &machine->threads); | 423 | rb_erase_init(&th->rb_node, &machine->threads); |
419 | RB_CLEAR_NODE(&th->rb_node); | 424 | RB_CLEAR_NODE(&th->rb_node); |
420 | thread__delete(th); | 425 | thread__put(th); |
421 | return NULL; | 426 | return NULL; |
422 | } | 427 | } |
423 | /* | 428 | /* |
@@ -441,7 +446,7 @@ struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, | |||
441 | struct thread *th; | 446 | struct thread *th; |
442 | 447 | ||
443 | pthread_rwlock_wrlock(&machine->threads_lock); | 448 | pthread_rwlock_wrlock(&machine->threads_lock); |
444 | th = thread__get(__machine__findnew_thread(machine, pid, tid)); | 449 | th = __machine__findnew_thread(machine, pid, tid); |
445 | pthread_rwlock_unlock(&machine->threads_lock); | 450 | pthread_rwlock_unlock(&machine->threads_lock); |
446 | return th; | 451 | return th; |
447 | } | 452 | } |
@@ -451,7 +456,7 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid, | |||
451 | { | 456 | { |
452 | struct thread *th; | 457 | struct thread *th; |
453 | pthread_rwlock_rdlock(&machine->threads_lock); | 458 | pthread_rwlock_rdlock(&machine->threads_lock); |
454 | th = thread__get(____machine__findnew_thread(machine, pid, tid, false)); | 459 | th = ____machine__findnew_thread(machine, pid, tid, false); |
455 | pthread_rwlock_unlock(&machine->threads_lock); | 460 | pthread_rwlock_unlock(&machine->threads_lock); |
456 | return th; | 461 | return th; |
457 | } | 462 | } |
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 355eecf6bf59..afc088dd7d20 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c | |||
@@ -1,7 +1,7 @@ | |||
1 | #include "perf.h" | 1 | #include "perf.h" |
2 | #include "util/util.h" | 2 | #include "util/util.h" |
3 | #include "util/debug.h" | 3 | #include "util/debug.h" |
4 | #include "util/parse-options.h" | 4 | #include <subcmd/parse-options.h> |
5 | #include "util/parse-branch-options.h" | 5 | #include "util/parse-branch-options.h" |
6 | 6 | ||
7 | #define BRANCH_OPT(n, m) \ | 7 | #define BRANCH_OPT(n, m) \ |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6fc8cd753e1a..4f7b0efdde2f 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -4,9 +4,9 @@ | |||
4 | #include "../perf.h" | 4 | #include "../perf.h" |
5 | #include "evlist.h" | 5 | #include "evlist.h" |
6 | #include "evsel.h" | 6 | #include "evsel.h" |
7 | #include "parse-options.h" | 7 | #include <subcmd/parse-options.h> |
8 | #include "parse-events.h" | 8 | #include "parse-events.h" |
9 | #include "exec_cmd.h" | 9 | #include <subcmd/exec-cmd.h> |
10 | #include "string.h" | 10 | #include "string.h" |
11 | #include "symbol.h" | 11 | #include "symbol.h" |
12 | #include "cache.h" | 12 | #include "cache.h" |
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c index 4f2c1c255d81..646ecf736aad 100644 --- a/tools/perf/util/parse-regs-options.c +++ b/tools/perf/util/parse-regs-options.c | |||
@@ -1,7 +1,7 @@ | |||
1 | #include "perf.h" | 1 | #include "perf.h" |
2 | #include "util/util.h" | 2 | #include "util/util.h" |
3 | #include "util/debug.h" | 3 | #include "util/debug.h" |
4 | #include "util/parse-options.h" | 4 | #include <subcmd/parse-options.h> |
5 | #include "util/parse-regs-options.h" | 5 | #include "util/parse-regs-options.h" |
6 | 6 | ||
7 | int | 7 | int |
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c index 5d13cb45b317..3654d964e49d 100644 --- a/tools/perf/util/path.c +++ b/tools/perf/util/path.c | |||
@@ -22,24 +22,6 @@ static const char *get_perf_dir(void) | |||
22 | return "."; | 22 | return "."; |
23 | } | 23 | } |
24 | 24 | ||
25 | /* | ||
26 | * If libc has strlcpy() then that version will override this | ||
27 | * implementation: | ||
28 | */ | ||
29 | size_t __weak strlcpy(char *dest, const char *src, size_t size) | ||
30 | { | ||
31 | size_t ret = strlen(src); | ||
32 | |||
33 | if (size) { | ||
34 | size_t len = (ret >= size) ? size - 1 : ret; | ||
35 | |||
36 | memcpy(dest, src, len); | ||
37 | dest[len] = '\0'; | ||
38 | } | ||
39 | |||
40 | return ret; | ||
41 | } | ||
42 | |||
43 | static char *get_pathname(void) | 25 | static char *get_pathname(void) |
44 | { | 26 | { |
45 | static char pathname_array[4][PATH_MAX]; | 27 | static char pathname_array[4][PATH_MAX]; |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 31228851e397..86f05e7a5566 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "debug.h" | 18 | #include "debug.h" |
19 | #include "header.h" | 19 | #include "header.h" |
20 | 20 | ||
21 | #include "parse-options.h" | 21 | #include <subcmd/parse-options.h> |
22 | #include "parse-events.h" | 22 | #include "parse-events.h" |
23 | #include "hist.h" | 23 | #include "hist.h" |
24 | #include "thread.h" | 24 | #include "thread.h" |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 0a9ae8014729..dfd00c6dad6e 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -19,8 +19,10 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine) | |||
19 | thread->mg = map_groups__new(machine); | 19 | thread->mg = map_groups__new(machine); |
20 | } else { | 20 | } else { |
21 | leader = __machine__findnew_thread(machine, pid, pid); | 21 | leader = __machine__findnew_thread(machine, pid, pid); |
22 | if (leader) | 22 | if (leader) { |
23 | thread->mg = map_groups__get(leader->mg); | 23 | thread->mg = map_groups__get(leader->mg); |
24 | thread__put(leader); | ||
25 | } | ||
24 | } | 26 | } |
25 | 27 | ||
26 | return thread->mg ? 0 : -1; | 28 | return thread->mg ? 0 : -1; |
@@ -53,7 +55,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
53 | goto err_thread; | 55 | goto err_thread; |
54 | 56 | ||
55 | list_add(&comm->list, &thread->comm_list); | 57 | list_add(&comm->list, &thread->comm_list); |
56 | atomic_set(&thread->refcnt, 0); | 58 | atomic_set(&thread->refcnt, 1); |
57 | RB_CLEAR_NODE(&thread->rb_node); | 59 | RB_CLEAR_NODE(&thread->rb_node); |
58 | } | 60 | } |
59 | 61 | ||
@@ -95,6 +97,10 @@ struct thread *thread__get(struct thread *thread) | |||
95 | void thread__put(struct thread *thread) | 97 | void thread__put(struct thread *thread) |
96 | { | 98 | { |
97 | if (thread && atomic_dec_and_test(&thread->refcnt)) { | 99 | if (thread && atomic_dec_and_test(&thread->refcnt)) { |
100 | /* | ||
101 | * Remove it from the dead_threads list, as last reference | ||
102 | * is gone. | ||
103 | */ | ||
98 | list_del_init(&thread->node); | 104 | list_del_init(&thread->node); |
99 | thread__delete(thread); | 105 | thread__delete(thread); |
100 | } | 106 | } |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 07da970a62a3..aff0cfd83662 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -352,7 +352,8 @@ void sighandler_dump_stack(int sig) | |||
352 | { | 352 | { |
353 | psignal(sig, "perf"); | 353 | psignal(sig, "perf"); |
354 | dump_stack(); | 354 | dump_stack(); |
355 | exit(sig); | 355 | signal(sig, SIG_DFL); |
356 | raise(sig); | ||
356 | } | 357 | } |
357 | 358 | ||
358 | int parse_nsec_time(const char *str, u64 *ptime) | 359 | int parse_nsec_time(const char *str, u64 *ptime) |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 150858f3b4f0..4b519c59bdc3 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -151,12 +151,6 @@ extern void set_warning_routine(void (*routine)(const char *err, va_list params) | |||
151 | extern int prefixcmp(const char *str, const char *prefix); | 151 | extern int prefixcmp(const char *str, const char *prefix); |
152 | extern void set_buildid_dir(const char *dir); | 152 | extern void set_buildid_dir(const char *dir); |
153 | 153 | ||
154 | static inline const char *skip_prefix(const char *str, const char *prefix) | ||
155 | { | ||
156 | size_t len = strlen(prefix); | ||
157 | return strncmp(str, prefix, len) ? NULL : str + len; | ||
158 | } | ||
159 | |||
160 | #ifdef __GLIBC_PREREQ | 154 | #ifdef __GLIBC_PREREQ |
161 | #if __GLIBC_PREREQ(2, 1) | 155 | #if __GLIBC_PREREQ(2, 1) |
162 | #define HAVE_STRCHRNUL | 156 | #define HAVE_STRCHRNUL |
@@ -187,14 +181,6 @@ static inline void *zalloc(size_t size) | |||
187 | 181 | ||
188 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) | 182 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) |
189 | 183 | ||
190 | static inline int has_extension(const char *filename, const char *ext) | ||
191 | { | ||
192 | size_t len = strlen(filename); | ||
193 | size_t extlen = strlen(ext); | ||
194 | |||
195 | return len > extlen && !memcmp(filename + len - extlen, ext, extlen); | ||
196 | } | ||
197 | |||
198 | /* Sane ctype - no locale, and works with signed chars */ | 184 | /* Sane ctype - no locale, and works with signed chars */ |
199 | #undef isascii | 185 | #undef isascii |
200 | #undef isspace | 186 | #undef isspace |