diff options
87 files changed, 1001 insertions, 882 deletions
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 0d9cbb426b44..ca4ab78425d1 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile | |||
| @@ -67,6 +67,8 @@ PLUGIN_DIR = -DPLUGIN_DIR="$(DESTDIR)/$(plugin_dir)" | |||
| 67 | PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' | 67 | PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' |
| 68 | endif | 68 | endif |
| 69 | 69 | ||
| 70 | include $(if $(BUILD_SRC),$(BUILD_SRC)/)../../scripts/Makefile.include | ||
| 71 | |||
| 70 | # copy a bit from Linux kbuild | 72 | # copy a bit from Linux kbuild |
| 71 | 73 | ||
| 72 | ifeq ("$(origin V)", "command line") | 74 | ifeq ("$(origin V)", "command line") |
| @@ -81,18 +83,13 @@ ifeq ("$(origin O)", "command line") | |||
| 81 | endif | 83 | endif |
| 82 | 84 | ||
| 83 | ifeq ($(BUILD_SRC),) | 85 | ifeq ($(BUILD_SRC),) |
| 84 | ifneq ($(BUILD_OUTPUT),) | 86 | ifneq ($(OUTPUT),) |
| 85 | 87 | ||
| 86 | define build_output | 88 | define build_output |
| 87 | $(if $(VERBOSE:1=),@)+$(MAKE) -C $(BUILD_OUTPUT) \ | 89 | $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \ |
| 88 | BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1 | 90 | BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1 |
| 89 | endef | 91 | endef |
| 90 | 92 | ||
| 91 | saved-output := $(BUILD_OUTPUT) | ||
| 92 | BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd) | ||
| 93 | $(if $(BUILD_OUTPUT),, \ | ||
| 94 | $(error output directory "$(saved-output)" does not exist)) | ||
| 95 | |||
| 96 | all: sub-make | 93 | all: sub-make |
| 97 | 94 | ||
| 98 | $(MAKECMDGOALS): sub-make | 95 | $(MAKECMDGOALS): sub-make |
| @@ -104,7 +101,7 @@ sub-make: force | |||
| 104 | # Leave processing to above invocation of make | 101 | # Leave processing to above invocation of make |
| 105 | skip-makefile := 1 | 102 | skip-makefile := 1 |
| 106 | 103 | ||
| 107 | endif # BUILD_OUTPUT | 104 | endif # OUTPUT |
| 108 | endif # BUILD_SRC | 105 | endif # BUILD_SRC |
| 109 | 106 | ||
| 110 | # We process the rest of the Makefile if this is the final invocation of make | 107 | # We process the rest of the Makefile if this is the final invocation of make |
| @@ -150,41 +147,14 @@ override CFLAGS += $(udis86-flags) -D_GNU_SOURCE | |||
| 150 | 147 | ||
| 151 | ifeq ($(VERBOSE),1) | 148 | ifeq ($(VERBOSE),1) |
| 152 | Q = | 149 | Q = |
| 153 | print_compile = | ||
| 154 | print_app_build = | ||
| 155 | print_fpic_compile = | ||
| 156 | print_shared_lib_compile = | ||
| 157 | print_plugin_obj_compile = | ||
| 158 | print_plugin_build = | ||
| 159 | print_install = | ||
| 160 | else | 150 | else |
| 161 | Q = @ | 151 | Q = @ |
| 162 | print_compile = echo ' CC '$(OBJ); | ||
| 163 | print_app_build = echo ' BUILD '$(OBJ); | ||
| 164 | print_fpic_compile = echo ' CC FPIC '$(OBJ); | ||
| 165 | print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ); | ||
| 166 | print_plugin_obj_compile = echo ' CC FPIC '$(OBJ); | ||
| 167 | print_plugin_build = echo ' BUILD PLUGIN '$(OBJ); | ||
| 168 | print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ); | ||
| 169 | print_install = echo ' INSTALL '$1; | ||
| 170 | endif | 152 | endif |
| 171 | 153 | ||
| 172 | do_fpic_compile = \ | ||
| 173 | ($(print_fpic_compile) \ | ||
| 174 | $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@) | ||
| 175 | |||
| 176 | do_app_build = \ | ||
| 177 | ($(print_app_build) \ | ||
| 178 | $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)) | ||
| 179 | |||
| 180 | do_compile_shared_library = \ | 154 | do_compile_shared_library = \ |
| 181 | ($(print_shared_lib_compile) \ | 155 | ($(print_shared_lib_compile) \ |
| 182 | $(CC) --shared $^ -o $@) | 156 | $(CC) --shared $^ -o $@) |
| 183 | 157 | ||
| 184 | do_compile_plugin_obj = \ | ||
| 185 | ($(print_plugin_obj_compile) \ | ||
| 186 | $(CC) -c $(CFLAGS) -fPIC -o $@ $<) | ||
| 187 | |||
| 188 | do_plugin_build = \ | 158 | do_plugin_build = \ |
| 189 | ($(print_plugin_build) \ | 159 | ($(print_plugin_build) \ |
| 190 | $(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<) | 160 | $(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<) |
| @@ -194,16 +164,13 @@ do_build_static_lib = \ | |||
| 194 | $(RM) $@; $(AR) rcs $@ $^) | 164 | $(RM) $@; $(AR) rcs $@ $^) |
| 195 | 165 | ||
| 196 | 166 | ||
| 197 | define do_compile | 167 | do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; |
| 198 | $(print_compile) \ | ||
| 199 | $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; | ||
| 200 | endef | ||
| 201 | 168 | ||
| 202 | $(obj)/%.o: $(src)/%.c | 169 | $(obj)/%.o: $(src)/%.c |
| 203 | $(Q)$(call do_compile) | 170 | $(call do_compile) |
| 204 | 171 | ||
| 205 | %.o: $(src)/%.c | 172 | %.o: $(src)/%.c |
| 206 | $(Q)$(call do_compile) | 173 | $(call do_compile) |
| 207 | 174 | ||
| 208 | PEVENT_LIB_OBJS = event-parse.o | 175 | PEVENT_LIB_OBJS = event-parse.o |
| 209 | PEVENT_LIB_OBJS += event-plugin.o | 176 | PEVENT_LIB_OBJS += event-plugin.o |
| @@ -237,21 +204,21 @@ all: all_cmd | |||
| 237 | all_cmd: $(CMD_TARGETS) | 204 | all_cmd: $(CMD_TARGETS) |
| 238 | 205 | ||
| 239 | libtraceevent.so: $(PEVENT_LIB_OBJS) | 206 | libtraceevent.so: $(PEVENT_LIB_OBJS) |
| 240 | $(Q)$(do_compile_shared_library) | 207 | $(QUIET_LINK)$(CC) --shared $^ -o $@ |
| 241 | 208 | ||
| 242 | libtraceevent.a: $(PEVENT_LIB_OBJS) | 209 | libtraceevent.a: $(PEVENT_LIB_OBJS) |
| 243 | $(Q)$(do_build_static_lib) | 210 | $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ |
| 244 | 211 | ||
| 245 | plugins: $(PLUGINS) | 212 | plugins: $(PLUGINS) |
| 246 | 213 | ||
| 247 | $(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS | 214 | $(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS |
| 248 | $(Q)$(do_fpic_compile) | 215 | $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@ |
| 249 | 216 | ||
| 250 | $(PLUGIN_OBJS): %.o : $(src)/%.c | 217 | $(PLUGIN_OBJS): %.o : $(src)/%.c |
| 251 | $(Q)$(do_compile_plugin_obj) | 218 | $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) -fPIC -o $@ $< |
| 252 | 219 | ||
| 253 | $(PLUGINS): %.so: %.o | 220 | $(PLUGINS): %.so: %.o |
| 254 | $(Q)$(do_plugin_build) | 221 | $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $< |
| 255 | 222 | ||
| 256 | define make_version.h | 223 | define make_version.h |
| 257 | (echo '/* This file is automatically generated. Do not modify. */'; \ | 224 | (echo '/* This file is automatically generated. Do not modify. */'; \ |
| @@ -333,28 +300,32 @@ TAGS: force | |||
| 333 | --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' | 300 | --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' |
| 334 | 301 | ||
| 335 | define do_install | 302 | define do_install |
| 336 | $(print_install) \ | ||
| 337 | if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ | 303 | if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ |
| 338 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ | 304 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ |
| 339 | fi; \ | 305 | fi; \ |
| 340 | $(INSTALL) $1 '$(DESTDIR_SQ)$2' | 306 | $(INSTALL) $1 '$(DESTDIR_SQ)$2' |
| 341 | endef | 307 | endef |
| 342 | 308 | ||
| 343 | install_lib: all_cmd install_plugins | 309 | define do_install_plugins |
| 344 | $(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ)) | 310 | for plugin in $1; do \ |
| 345 | 311 | $(call do_install,$$plugin,$(plugin_dir_SQ)); \ | |
| 346 | PLUGINS_INSTALL = $(subst .so,.install,$(PLUGINS)) | 312 | done |
| 313 | endef | ||
| 347 | 314 | ||
| 348 | $(PLUGINS_INSTALL): %.install : %.so force | 315 | install_lib: all_cmd install_plugins |
| 349 | $(Q)$(call do_install,$<,$(plugin_dir_SQ)) | 316 | $(call QUIET_INSTALL, $(LIB_FILE)) \ |
| 317 | $(call do_install,$(LIB_FILE),$(bindir_SQ)) | ||
| 350 | 318 | ||
| 351 | install_plugins: $(PLUGINS_INSTALL) | 319 | install_plugins: $(PLUGINS) |
| 320 | $(call QUIET_INSTALL, trace_plugins) \ | ||
| 321 | $(call do_install_plugins, $(PLUGINS)) | ||
| 352 | 322 | ||
| 353 | install: install_lib | 323 | install: install_lib |
| 354 | 324 | ||
| 355 | clean: | 325 | clean: |
| 356 | $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d | 326 | $(call QUIET_CLEAN, libtraceevent) \ |
| 357 | $(RM) TRACEEVENT-CFLAGS tags TAGS | 327 | $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ |
| 328 | $(RM) TRACEEVENT-CFLAGS tags TAGS | ||
| 358 | 329 | ||
| 359 | endif # skip-makefile | 330 | endif # skip-makefile |
| 360 | 331 | ||
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 22566c271275..2ce565a73dd5 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -5230,22 +5230,7 @@ int pevent_strerror(struct pevent *pevent __maybe_unused, | |||
| 5230 | 5230 | ||
| 5231 | idx = errnum - __PEVENT_ERRNO__START - 1; | 5231 | idx = errnum - __PEVENT_ERRNO__START - 1; |
| 5232 | msg = pevent_error_str[idx]; | 5232 | msg = pevent_error_str[idx]; |
| 5233 | 5233 | snprintf(buf, buflen, "%s", msg); | |
| 5234 | switch (errnum) { | ||
| 5235 | case PEVENT_ERRNO__MEM_ALLOC_FAILED: | ||
| 5236 | case PEVENT_ERRNO__PARSE_EVENT_FAILED: | ||
| 5237 | case PEVENT_ERRNO__READ_ID_FAILED: | ||
| 5238 | case PEVENT_ERRNO__READ_FORMAT_FAILED: | ||
| 5239 | case PEVENT_ERRNO__READ_PRINT_FAILED: | ||
| 5240 | case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: | ||
| 5241 | case PEVENT_ERRNO__INVALID_ARG_TYPE: | ||
| 5242 | snprintf(buf, buflen, "%s", msg); | ||
| 5243 | break; | ||
| 5244 | |||
| 5245 | default: | ||
| 5246 | /* cannot reach here */ | ||
| 5247 | break; | ||
| 5248 | } | ||
| 5249 | 5234 | ||
| 5250 | return 0; | 5235 | return 0; |
| 5251 | } | 5236 | } |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 3ad784f5f647..cf5db9013f2c 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
| @@ -851,10 +851,13 @@ struct filter_type { | |||
| 851 | struct filter_arg *filter; | 851 | struct filter_arg *filter; |
| 852 | }; | 852 | }; |
| 853 | 853 | ||
| 854 | #define PEVENT_FILTER_ERROR_BUFSZ 1024 | ||
| 855 | |||
| 854 | struct event_filter { | 856 | struct event_filter { |
| 855 | struct pevent *pevent; | 857 | struct pevent *pevent; |
| 856 | int filters; | 858 | int filters; |
| 857 | struct filter_type *event_filters; | 859 | struct filter_type *event_filters; |
| 860 | char error_buffer[PEVENT_FILTER_ERROR_BUFSZ]; | ||
| 858 | }; | 861 | }; |
| 859 | 862 | ||
| 860 | struct event_filter *pevent_filter_alloc(struct pevent *pevent); | 863 | struct event_filter *pevent_filter_alloc(struct pevent *pevent); |
| @@ -874,10 +877,12 @@ enum filter_trivial_type { | |||
| 874 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | 877 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, |
| 875 | const char *filter_str); | 878 | const char *filter_str); |
| 876 | 879 | ||
| 877 | |||
| 878 | enum pevent_errno pevent_filter_match(struct event_filter *filter, | 880 | enum pevent_errno pevent_filter_match(struct event_filter *filter, |
| 879 | struct pevent_record *record); | 881 | struct pevent_record *record); |
| 880 | 882 | ||
| 883 | int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, | ||
| 884 | char *buf, size_t buflen); | ||
| 885 | |||
| 881 | int pevent_event_filtered(struct event_filter *filter, | 886 | int pevent_event_filtered(struct event_filter *filter, |
| 882 | int event_id); | 887 | int event_id); |
| 883 | 888 | ||
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index e2842b926759..b50234402fc2 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c | |||
| @@ -38,55 +38,31 @@ struct event_list { | |||
| 38 | struct event_format *event; | 38 | struct event_format *event; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | #define MAX_ERR_STR_SIZE 256 | 41 | static void show_error(char *error_buf, const char *fmt, ...) |
| 42 | |||
| 43 | static void show_error(char **error_str, const char *fmt, ...) | ||
| 44 | { | 42 | { |
| 45 | unsigned long long index; | 43 | unsigned long long index; |
| 46 | const char *input; | 44 | const char *input; |
| 47 | char *error; | ||
| 48 | va_list ap; | 45 | va_list ap; |
| 49 | int len; | 46 | int len; |
| 50 | int i; | 47 | int i; |
| 51 | 48 | ||
| 52 | if (!error_str) | ||
| 53 | return; | ||
| 54 | |||
| 55 | input = pevent_get_input_buf(); | 49 | input = pevent_get_input_buf(); |
| 56 | index = pevent_get_input_buf_ptr(); | 50 | index = pevent_get_input_buf_ptr(); |
| 57 | len = input ? strlen(input) : 0; | 51 | len = input ? strlen(input) : 0; |
| 58 | 52 | ||
| 59 | error = malloc(MAX_ERR_STR_SIZE + (len*2) + 3); | ||
| 60 | if (error == NULL) { | ||
| 61 | /* | ||
| 62 | * Maybe it's due to len is too long. | ||
| 63 | * Retry without the input buffer part. | ||
| 64 | */ | ||
| 65 | len = 0; | ||
| 66 | |||
| 67 | error = malloc(MAX_ERR_STR_SIZE); | ||
| 68 | if (error == NULL) { | ||
| 69 | /* no memory */ | ||
| 70 | *error_str = NULL; | ||
| 71 | return; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | if (len) { | 53 | if (len) { |
| 76 | strcpy(error, input); | 54 | strcpy(error_buf, input); |
| 77 | error[len] = '\n'; | 55 | error_buf[len] = '\n'; |
| 78 | for (i = 1; i < len && i < index; i++) | 56 | for (i = 1; i < len && i < index; i++) |
| 79 | error[len+i] = ' '; | 57 | error_buf[len+i] = ' '; |
| 80 | error[len + i] = '^'; | 58 | error_buf[len + i] = '^'; |
| 81 | error[len + i + 1] = '\n'; | 59 | error_buf[len + i + 1] = '\n'; |
| 82 | len += i+2; | 60 | len += i+2; |
| 83 | } | 61 | } |
| 84 | 62 | ||
| 85 | va_start(ap, fmt); | 63 | va_start(ap, fmt); |
| 86 | vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap); | 64 | vsnprintf(error_buf + len, PEVENT_FILTER_ERROR_BUFSZ - len, fmt, ap); |
| 87 | va_end(ap); | 65 | va_end(ap); |
| 88 | |||
| 89 | *error_str = error; | ||
| 90 | } | 66 | } |
| 91 | 67 | ||
| 92 | static void free_token(char *token) | 68 | static void free_token(char *token) |
| @@ -370,7 +346,7 @@ static void free_events(struct event_list *events) | |||
| 370 | 346 | ||
| 371 | static enum pevent_errno | 347 | static enum pevent_errno |
| 372 | create_arg_item(struct event_format *event, const char *token, | 348 | create_arg_item(struct event_format *event, const char *token, |
| 373 | enum event_type type, struct filter_arg **parg, char **error_str) | 349 | enum event_type type, struct filter_arg **parg, char *error_str) |
| 374 | { | 350 | { |
| 375 | struct format_field *field; | 351 | struct format_field *field; |
| 376 | struct filter_arg *arg; | 352 | struct filter_arg *arg; |
| @@ -474,7 +450,7 @@ create_arg_cmp(enum filter_exp_type etype) | |||
| 474 | } | 450 | } |
| 475 | 451 | ||
| 476 | static enum pevent_errno | 452 | static enum pevent_errno |
| 477 | add_right(struct filter_arg *op, struct filter_arg *arg, char **error_str) | 453 | add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str) |
| 478 | { | 454 | { |
| 479 | struct filter_arg *left; | 455 | struct filter_arg *left; |
| 480 | char *str; | 456 | char *str; |
| @@ -786,7 +762,7 @@ enum filter_vals { | |||
| 786 | 762 | ||
| 787 | static enum pevent_errno | 763 | static enum pevent_errno |
| 788 | reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, | 764 | reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, |
| 789 | struct filter_arg *arg, char **error_str) | 765 | struct filter_arg *arg, char *error_str) |
| 790 | { | 766 | { |
| 791 | struct filter_arg *other_child; | 767 | struct filter_arg *other_child; |
| 792 | struct filter_arg **ptr; | 768 | struct filter_arg **ptr; |
| @@ -838,7 +814,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, | |||
| 838 | 814 | ||
| 839 | /* Returns either filter_vals (success) or pevent_errno (failfure) */ | 815 | /* Returns either filter_vals (success) or pevent_errno (failfure) */ |
| 840 | static int test_arg(struct filter_arg *parent, struct filter_arg *arg, | 816 | static int test_arg(struct filter_arg *parent, struct filter_arg *arg, |
| 841 | char **error_str) | 817 | char *error_str) |
| 842 | { | 818 | { |
| 843 | int lval, rval; | 819 | int lval, rval; |
| 844 | 820 | ||
| @@ -938,7 +914,7 @@ static int test_arg(struct filter_arg *parent, struct filter_arg *arg, | |||
| 938 | 914 | ||
| 939 | /* Remove any unknown event fields */ | 915 | /* Remove any unknown event fields */ |
| 940 | static int collapse_tree(struct filter_arg *arg, | 916 | static int collapse_tree(struct filter_arg *arg, |
| 941 | struct filter_arg **arg_collapsed, char **error_str) | 917 | struct filter_arg **arg_collapsed, char *error_str) |
| 942 | { | 918 | { |
| 943 | int ret; | 919 | int ret; |
| 944 | 920 | ||
| @@ -973,7 +949,7 @@ static int collapse_tree(struct filter_arg *arg, | |||
| 973 | 949 | ||
| 974 | static enum pevent_errno | 950 | static enum pevent_errno |
| 975 | process_filter(struct event_format *event, struct filter_arg **parg, | 951 | process_filter(struct event_format *event, struct filter_arg **parg, |
| 976 | char **error_str, int not) | 952 | char *error_str, int not) |
| 977 | { | 953 | { |
| 978 | enum event_type type; | 954 | enum event_type type; |
| 979 | char *token = NULL; | 955 | char *token = NULL; |
| @@ -1211,7 +1187,7 @@ process_filter(struct event_format *event, struct filter_arg **parg, | |||
| 1211 | 1187 | ||
| 1212 | static enum pevent_errno | 1188 | static enum pevent_errno |
| 1213 | process_event(struct event_format *event, const char *filter_str, | 1189 | process_event(struct event_format *event, const char *filter_str, |
| 1214 | struct filter_arg **parg, char **error_str) | 1190 | struct filter_arg **parg, char *error_str) |
| 1215 | { | 1191 | { |
| 1216 | int ret; | 1192 | int ret; |
| 1217 | 1193 | ||
| @@ -1236,7 +1212,7 @@ process_event(struct event_format *event, const char *filter_str, | |||
| 1236 | 1212 | ||
| 1237 | static enum pevent_errno | 1213 | static enum pevent_errno |
| 1238 | filter_event(struct event_filter *filter, struct event_format *event, | 1214 | filter_event(struct event_filter *filter, struct event_format *event, |
| 1239 | const char *filter_str, char **error_str) | 1215 | const char *filter_str, char *error_str) |
| 1240 | { | 1216 | { |
| 1241 | struct filter_type *filter_type; | 1217 | struct filter_type *filter_type; |
| 1242 | struct filter_arg *arg; | 1218 | struct filter_arg *arg; |
| @@ -1268,13 +1244,21 @@ filter_event(struct event_filter *filter, struct event_format *event, | |||
| 1268 | return 0; | 1244 | return 0; |
| 1269 | } | 1245 | } |
| 1270 | 1246 | ||
| 1247 | static void filter_init_error_buf(struct event_filter *filter) | ||
| 1248 | { | ||
| 1249 | /* clear buffer to reset show error */ | ||
| 1250 | pevent_buffer_init("", 0); | ||
| 1251 | filter->error_buffer[0] = '\0'; | ||
| 1252 | } | ||
| 1253 | |||
| 1271 | /** | 1254 | /** |
| 1272 | * pevent_filter_add_filter_str - add a new filter | 1255 | * pevent_filter_add_filter_str - add a new filter |
| 1273 | * @filter: the event filter to add to | 1256 | * @filter: the event filter to add to |
| 1274 | * @filter_str: the filter string that contains the filter | 1257 | * @filter_str: the filter string that contains the filter |
| 1275 | * | 1258 | * |
| 1276 | * Returns 0 if the filter was successfully added or a | 1259 | * Returns 0 if the filter was successfully added or a |
| 1277 | * negative error code. | 1260 | * negative error code. Use pevent_filter_strerror() to see |
| 1261 | * actual error message in case of error. | ||
| 1278 | */ | 1262 | */ |
| 1279 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | 1263 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, |
| 1280 | const char *filter_str) | 1264 | const char *filter_str) |
| @@ -1291,10 +1275,8 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | |||
| 1291 | enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */ | 1275 | enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */ |
| 1292 | int len; | 1276 | int len; |
| 1293 | int ret; | 1277 | int ret; |
| 1294 | char *error_str = NULL; | ||
| 1295 | 1278 | ||
| 1296 | /* clear buffer to reset show error */ | 1279 | filter_init_error_buf(filter); |
| 1297 | pevent_buffer_init("", 0); | ||
| 1298 | 1280 | ||
| 1299 | filter_start = strchr(filter_str, ':'); | 1281 | filter_start = strchr(filter_str, ':'); |
| 1300 | if (filter_start) | 1282 | if (filter_start) |
| @@ -1353,7 +1335,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | |||
| 1353 | /* filter starts here */ | 1335 | /* filter starts here */ |
| 1354 | for (event = events; event; event = event->next) { | 1336 | for (event = events; event; event = event->next) { |
| 1355 | ret = filter_event(filter, event->event, filter_start, | 1337 | ret = filter_event(filter, event->event, filter_start, |
| 1356 | &error_str); | 1338 | filter->error_buffer); |
| 1357 | /* Failures are returned if a parse error happened */ | 1339 | /* Failures are returned if a parse error happened */ |
| 1358 | if (ret < 0) | 1340 | if (ret < 0) |
| 1359 | rtn = ret; | 1341 | rtn = ret; |
| @@ -1382,6 +1364,32 @@ static void free_filter_type(struct filter_type *filter_type) | |||
| 1382 | } | 1364 | } |
| 1383 | 1365 | ||
| 1384 | /** | 1366 | /** |
| 1367 | * pevent_filter_strerror - fill error message in a buffer | ||
| 1368 | * @filter: the event filter contains error | ||
| 1369 | * @err: the error code | ||
| 1370 | * @buf: the buffer to be filled in | ||
| 1371 | * @buflen: the size of the buffer | ||
| 1372 | * | ||
| 1373 | * Returns 0 if message was filled successfully, -1 if error | ||
| 1374 | */ | ||
| 1375 | int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, | ||
| 1376 | char *buf, size_t buflen) | ||
| 1377 | { | ||
| 1378 | if (err <= __PEVENT_ERRNO__START || err >= __PEVENT_ERRNO__END) | ||
| 1379 | return -1; | ||
| 1380 | |||
| 1381 | if (strlen(filter->error_buffer) > 0) { | ||
| 1382 | size_t len = snprintf(buf, buflen, "%s", filter->error_buffer); | ||
| 1383 | |||
| 1384 | if (len > buflen) | ||
| 1385 | return -1; | ||
| 1386 | return 0; | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | return pevent_strerror(filter->pevent, err, buf, buflen); | ||
| 1390 | } | ||
| 1391 | |||
| 1392 | /** | ||
| 1385 | * pevent_filter_remove_event - remove a filter for an event | 1393 | * pevent_filter_remove_event - remove a filter for an event |
| 1386 | * @filter: the event filter to remove from | 1394 | * @filter: the event filter to remove from |
| 1387 | * @event_id: the event to remove a filter for | 1395 | * @event_id: the event to remove a filter for |
| @@ -2027,6 +2035,8 @@ enum pevent_errno pevent_filter_match(struct event_filter *filter, | |||
| 2027 | int ret; | 2035 | int ret; |
| 2028 | enum pevent_errno err = 0; | 2036 | enum pevent_errno err = 0; |
| 2029 | 2037 | ||
| 2038 | filter_init_error_buf(filter); | ||
| 2039 | |||
| 2030 | if (!filter->filters) | 2040 | if (!filter->filters) |
| 2031 | return PEVENT_ERRNO__NO_FILTER; | 2041 | return PEVENT_ERRNO__NO_FILTER; |
| 2032 | 2042 | ||
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 97a2145e4cc6..3638b0bd20dc 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -489,6 +489,7 @@ ifndef NO_SLANG | |||
| 489 | LIB_OBJS += $(OUTPUT)ui/browsers/hists.o | 489 | LIB_OBJS += $(OUTPUT)ui/browsers/hists.o |
| 490 | LIB_OBJS += $(OUTPUT)ui/browsers/map.o | 490 | LIB_OBJS += $(OUTPUT)ui/browsers/map.o |
| 491 | LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o | 491 | LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o |
| 492 | LIB_OBJS += $(OUTPUT)ui/browsers/header.o | ||
| 492 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o | 493 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o |
| 493 | LIB_OBJS += $(OUTPUT)ui/tui/util.o | 494 | LIB_OBJS += $(OUTPUT)ui/tui/util.o |
| 494 | LIB_OBJS += $(OUTPUT)ui/tui/helpline.o | 495 | LIB_OBJS += $(OUTPUT)ui/tui/helpline.o |
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index aacef07ebf31..42faf369211c 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c | |||
| @@ -154,8 +154,7 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, | |||
| 154 | } | 154 | } |
| 155 | if (lookup_path(buf)) | 155 | if (lookup_path(buf)) |
| 156 | goto out; | 156 | goto out; |
| 157 | free(buf); | 157 | zfree(&buf); |
| 158 | buf = NULL; | ||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | if (!strcmp(arch, "arm")) | 160 | if (!strcmp(arch, "arm")) |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6fd52c8fa682..ab65057a0317 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -69,15 +69,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, | |||
| 69 | if (he == NULL) | 69 | if (he == NULL) |
| 70 | return -ENOMEM; | 70 | return -ENOMEM; |
| 71 | 71 | ||
| 72 | ret = 0; | 72 | ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
| 73 | if (he->ms.sym != NULL) { | ||
| 74 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
| 75 | if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0) | ||
| 76 | return -ENOMEM; | ||
| 77 | |||
| 78 | ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
| 79 | } | ||
| 80 | |||
| 81 | evsel->hists.stats.total_period += sample->period; | 73 | evsel->hists.stats.total_period += sample->period; |
| 82 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 74 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
| 83 | return ret; | 75 | return ret; |
| @@ -188,8 +180,7 @@ find_next: | |||
| 188 | * symbol, free he->ms.sym->src to signal we already | 180 | * symbol, free he->ms.sym->src to signal we already |
| 189 | * processed this symbol. | 181 | * processed this symbol. |
| 190 | */ | 182 | */ |
| 191 | free(notes->src); | 183 | zfree(¬es->src); |
| 192 | notes->src = NULL; | ||
| 193 | } | 184 | } |
| 194 | } | 185 | } |
| 195 | } | 186 | } |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 2a85cc9a2d09..e6a0844bc2f0 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -654,7 +654,7 @@ static void data__free(struct data__file *d) | |||
| 654 | for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) { | 654 | for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) { |
| 655 | struct diff_hpp_fmt *fmt = &d->fmt[col]; | 655 | struct diff_hpp_fmt *fmt = &d->fmt[col]; |
| 656 | 656 | ||
| 657 | free(fmt->header); | 657 | zfree(&fmt->header); |
| 658 | } | 658 | } |
| 659 | } | 659 | } |
| 660 | 660 | ||
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 6a2508589460..c9f6d74e1fd7 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
| @@ -22,14 +22,13 @@ | |||
| 22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
| 23 | 23 | ||
| 24 | struct perf_inject { | 24 | struct perf_inject { |
| 25 | struct perf_tool tool; | 25 | struct perf_tool tool; |
| 26 | bool build_ids; | 26 | bool build_ids; |
| 27 | bool sched_stat; | 27 | bool sched_stat; |
| 28 | const char *input_name; | 28 | const char *input_name; |
| 29 | int pipe_output, | 29 | struct perf_data_file output; |
| 30 | output; | 30 | u64 bytes_written; |
| 31 | u64 bytes_written; | 31 | struct list_head samples; |
| 32 | struct list_head samples; | ||
| 33 | }; | 32 | }; |
| 34 | 33 | ||
| 35 | struct event_entry { | 34 | struct event_entry { |
| @@ -42,21 +41,14 @@ static int perf_event__repipe_synth(struct perf_tool *tool, | |||
| 42 | union perf_event *event) | 41 | union perf_event *event) |
| 43 | { | 42 | { |
| 44 | struct perf_inject *inject = container_of(tool, struct perf_inject, tool); | 43 | struct perf_inject *inject = container_of(tool, struct perf_inject, tool); |
| 45 | uint32_t size; | 44 | ssize_t size; |
| 46 | void *buf = event; | ||
| 47 | 45 | ||
| 48 | size = event->header.size; | 46 | size = perf_data_file__write(&inject->output, event, |
| 49 | 47 | event->header.size); | |
| 50 | while (size) { | 48 | if (size < 0) |
| 51 | int ret = write(inject->output, buf, size); | 49 | return -errno; |
| 52 | if (ret < 0) | ||
| 53 | return -errno; | ||
| 54 | |||
| 55 | size -= ret; | ||
| 56 | buf += ret; | ||
| 57 | inject->bytes_written += ret; | ||
| 58 | } | ||
| 59 | 50 | ||
| 51 | inject->bytes_written += size; | ||
| 60 | return 0; | 52 | return 0; |
| 61 | } | 53 | } |
| 62 | 54 | ||
| @@ -80,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool, | |||
| 80 | if (ret) | 72 | if (ret) |
| 81 | return ret; | 73 | return ret; |
| 82 | 74 | ||
| 83 | if (!inject->pipe_output) | 75 | if (&inject->output.is_pipe) |
| 84 | return 0; | 76 | return 0; |
| 85 | 77 | ||
| 86 | return perf_event__repipe_synth(tool, event); | 78 | return perf_event__repipe_synth(tool, event); |
| @@ -355,6 +347,7 @@ static int __cmd_inject(struct perf_inject *inject) | |||
| 355 | .path = inject->input_name, | 347 | .path = inject->input_name, |
| 356 | .mode = PERF_DATA_MODE_READ, | 348 | .mode = PERF_DATA_MODE_READ, |
| 357 | }; | 349 | }; |
| 350 | struct perf_data_file *file_out = &inject->output; | ||
| 358 | 351 | ||
| 359 | signal(SIGINT, sig_handler); | 352 | signal(SIGINT, sig_handler); |
| 360 | 353 | ||
| @@ -391,14 +384,14 @@ static int __cmd_inject(struct perf_inject *inject) | |||
| 391 | } | 384 | } |
| 392 | } | 385 | } |
| 393 | 386 | ||
| 394 | if (!inject->pipe_output) | 387 | if (!file_out->is_pipe) |
| 395 | lseek(inject->output, session->header.data_offset, SEEK_SET); | 388 | lseek(file_out->fd, session->header.data_offset, SEEK_SET); |
| 396 | 389 | ||
| 397 | ret = perf_session__process_events(session, &inject->tool); | 390 | ret = perf_session__process_events(session, &inject->tool); |
| 398 | 391 | ||
| 399 | if (!inject->pipe_output) { | 392 | if (!file_out->is_pipe) { |
| 400 | session->header.data_size = inject->bytes_written; | 393 | session->header.data_size = inject->bytes_written; |
| 401 | perf_session__write_header(session, session->evlist, inject->output, true); | 394 | perf_session__write_header(session, session->evlist, file_out->fd, true); |
| 402 | } | 395 | } |
| 403 | 396 | ||
| 404 | perf_session__delete(session); | 397 | perf_session__delete(session); |
| @@ -427,14 +420,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 427 | }, | 420 | }, |
| 428 | .input_name = "-", | 421 | .input_name = "-", |
| 429 | .samples = LIST_HEAD_INIT(inject.samples), | 422 | .samples = LIST_HEAD_INIT(inject.samples), |
| 423 | .output = { | ||
| 424 | .path = "-", | ||
| 425 | .mode = PERF_DATA_MODE_WRITE, | ||
| 426 | }, | ||
| 430 | }; | 427 | }; |
| 431 | const char *output_name = "-"; | ||
| 432 | const struct option options[] = { | 428 | const struct option options[] = { |
| 433 | OPT_BOOLEAN('b', "build-ids", &inject.build_ids, | 429 | OPT_BOOLEAN('b', "build-ids", &inject.build_ids, |
| 434 | "Inject build-ids into the output stream"), | 430 | "Inject build-ids into the output stream"), |
| 435 | OPT_STRING('i', "input", &inject.input_name, "file", | 431 | OPT_STRING('i', "input", &inject.input_name, "file", |
| 436 | "input file name"), | 432 | "input file name"), |
| 437 | OPT_STRING('o', "output", &output_name, "file", | 433 | OPT_STRING('o', "output", &inject.output.path, "file", |
| 438 | "output file name"), | 434 | "output file name"), |
| 439 | OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, | 435 | OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, |
| 440 | "Merge sched-stat and sched-switch for getting events " | 436 | "Merge sched-stat and sched-switch for getting events " |
| @@ -456,16 +452,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 456 | if (argc) | 452 | if (argc) |
| 457 | usage_with_options(inject_usage, options); | 453 | usage_with_options(inject_usage, options); |
| 458 | 454 | ||
| 459 | if (!strcmp(output_name, "-")) { | 455 | if (perf_data_file__open(&inject.output)) { |
| 460 | inject.pipe_output = 1; | 456 | perror("failed to create output file"); |
| 461 | inject.output = STDOUT_FILENO; | 457 | return -1; |
| 462 | } else { | ||
| 463 | inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC, | ||
| 464 | S_IRUSR | S_IWUSR); | ||
| 465 | if (inject.output < 0) { | ||
| 466 | perror("failed to create output file"); | ||
| 467 | return -1; | ||
| 468 | } | ||
| 469 | } | 458 | } |
| 470 | 459 | ||
| 471 | if (symbol__init() < 0) | 460 | if (symbol__init() < 0) |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 154b397a5d27..a6ec1052c291 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -89,7 +89,7 @@ struct exit_reasons_table { | |||
| 89 | 89 | ||
| 90 | struct perf_kvm_stat { | 90 | struct perf_kvm_stat { |
| 91 | struct perf_tool tool; | 91 | struct perf_tool tool; |
| 92 | struct perf_record_opts opts; | 92 | struct record_opts opts; |
| 93 | struct perf_evlist *evlist; | 93 | struct perf_evlist *evlist; |
| 94 | struct perf_session *session; | 94 | struct perf_session *session; |
| 95 | 95 | ||
| @@ -1158,9 +1158,7 @@ out: | |||
| 1158 | if (kvm->timerfd >= 0) | 1158 | if (kvm->timerfd >= 0) |
| 1159 | close(kvm->timerfd); | 1159 | close(kvm->timerfd); |
| 1160 | 1160 | ||
| 1161 | if (pollfds) | 1161 | free(pollfds); |
| 1162 | free(pollfds); | ||
| 1163 | |||
| 1164 | return err; | 1162 | return err; |
| 1165 | } | 1163 | } |
| 1166 | 1164 | ||
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 31c00f186da1..2e3ade69a58e 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
| @@ -62,7 +62,6 @@ static int | |||
| 62 | dump_raw_samples(struct perf_tool *tool, | 62 | dump_raw_samples(struct perf_tool *tool, |
| 63 | union perf_event *event, | 63 | union perf_event *event, |
| 64 | struct perf_sample *sample, | 64 | struct perf_sample *sample, |
| 65 | struct perf_evsel *evsel __maybe_unused, | ||
| 66 | struct machine *machine) | 65 | struct machine *machine) |
| 67 | { | 66 | { |
| 68 | struct perf_mem *mem = container_of(tool, struct perf_mem, tool); | 67 | struct perf_mem *mem = container_of(tool, struct perf_mem, tool); |
| @@ -112,10 +111,10 @@ dump_raw_samples(struct perf_tool *tool, | |||
| 112 | static int process_sample_event(struct perf_tool *tool, | 111 | static int process_sample_event(struct perf_tool *tool, |
| 113 | union perf_event *event, | 112 | union perf_event *event, |
| 114 | struct perf_sample *sample, | 113 | struct perf_sample *sample, |
| 115 | struct perf_evsel *evsel, | 114 | struct perf_evsel *evsel __maybe_unused, |
| 116 | struct machine *machine) | 115 | struct machine *machine) |
| 117 | { | 116 | { |
| 118 | return dump_raw_samples(tool, event, sample, evsel, machine); | 117 | return dump_raw_samples(tool, event, sample, machine); |
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | static int report_raw_events(struct perf_mem *mem) | 120 | static int report_raw_events(struct perf_mem *mem) |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index c98ccb570509..43ff33d0007b 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
| @@ -169,6 +169,7 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
| 169 | int unset __maybe_unused) | 169 | int unset __maybe_unused) |
| 170 | { | 170 | { |
| 171 | int ret = -ENOENT; | 171 | int ret = -ENOENT; |
| 172 | char *tmp; | ||
| 172 | 173 | ||
| 173 | if (str && !params.target) { | 174 | if (str && !params.target) { |
| 174 | if (!strcmp(opt->long_name, "exec")) | 175 | if (!strcmp(opt->long_name, "exec")) |
| @@ -180,7 +181,19 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
| 180 | else | 181 | else |
| 181 | return ret; | 182 | return ret; |
| 182 | 183 | ||
| 183 | params.target = str; | 184 | /* Expand given path to absolute path, except for modulename */ |
| 185 | if (params.uprobes || strchr(str, '/')) { | ||
| 186 | tmp = realpath(str, NULL); | ||
| 187 | if (!tmp) { | ||
| 188 | pr_warning("Failed to get the absolute path of %s: %m\n", str); | ||
| 189 | return ret; | ||
| 190 | } | ||
| 191 | } else { | ||
| 192 | tmp = strdup(str); | ||
| 193 | if (!tmp) | ||
| 194 | return -ENOMEM; | ||
| 195 | } | ||
| 196 | params.target = tmp; | ||
| 184 | ret = 0; | 197 | ret = 0; |
| 185 | } | 198 | } |
| 186 | 199 | ||
| @@ -411,7 +424,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 411 | } | 424 | } |
| 412 | 425 | ||
| 413 | #ifdef HAVE_DWARF_SUPPORT | 426 | #ifdef HAVE_DWARF_SUPPORT |
| 414 | if (params.show_lines && !params.uprobes) { | 427 | if (params.show_lines) { |
| 415 | if (params.mod_events) { | 428 | if (params.mod_events) { |
| 416 | pr_err(" Error: Don't use --line with" | 429 | pr_err(" Error: Don't use --line with" |
| 417 | " --add/--del.\n"); | 430 | " --add/--del.\n"); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index c1c1200d2f0a..6ec0cbc2a5d5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -62,9 +62,9 @@ static void __handle_on_exit_funcs(void) | |||
| 62 | } | 62 | } |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | struct perf_record { | 65 | struct record { |
| 66 | struct perf_tool tool; | 66 | struct perf_tool tool; |
| 67 | struct perf_record_opts opts; | 67 | struct record_opts opts; |
| 68 | u64 bytes_written; | 68 | u64 bytes_written; |
| 69 | struct perf_data_file file; | 69 | struct perf_data_file file; |
| 70 | struct perf_evlist *evlist; | 70 | struct perf_evlist *evlist; |
| @@ -76,24 +76,14 @@ struct perf_record { | |||
| 76 | long samples; | 76 | long samples; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | static int perf_record__write(struct perf_record *rec, void *buf, size_t size) | 79 | static int record__write(struct record *rec, void *bf, size_t size) |
| 80 | { | 80 | { |
| 81 | struct perf_data_file *file = &rec->file; | 81 | if (perf_data_file__write(rec->session->file, bf, size) < 0) { |
| 82 | 82 | pr_err("failed to write perf data, error: %m\n"); | |
| 83 | while (size) { | 83 | return -1; |
| 84 | ssize_t ret = write(file->fd, buf, size); | ||
| 85 | |||
| 86 | if (ret < 0) { | ||
| 87 | pr_err("failed to write perf data, error: %m\n"); | ||
| 88 | return -1; | ||
| 89 | } | ||
| 90 | |||
| 91 | size -= ret; | ||
| 92 | buf += ret; | ||
| 93 | |||
| 94 | rec->bytes_written += ret; | ||
| 95 | } | 84 | } |
| 96 | 85 | ||
| 86 | rec->bytes_written += size; | ||
| 97 | return 0; | 87 | return 0; |
| 98 | } | 88 | } |
| 99 | 89 | ||
| @@ -102,12 +92,11 @@ static int process_synthesized_event(struct perf_tool *tool, | |||
| 102 | struct perf_sample *sample __maybe_unused, | 92 | struct perf_sample *sample __maybe_unused, |
| 103 | struct machine *machine __maybe_unused) | 93 | struct machine *machine __maybe_unused) |
| 104 | { | 94 | { |
| 105 | struct perf_record *rec = container_of(tool, struct perf_record, tool); | 95 | struct record *rec = container_of(tool, struct record, tool); |
| 106 | return perf_record__write(rec, event, event->header.size); | 96 | return record__write(rec, event, event->header.size); |
| 107 | } | 97 | } |
| 108 | 98 | ||
| 109 | static int perf_record__mmap_read(struct perf_record *rec, | 99 | static int record__mmap_read(struct record *rec, struct perf_mmap *md) |
| 110 | struct perf_mmap *md) | ||
| 111 | { | 100 | { |
| 112 | unsigned int head = perf_mmap__read_head(md); | 101 | unsigned int head = perf_mmap__read_head(md); |
| 113 | unsigned int old = md->prev; | 102 | unsigned int old = md->prev; |
| @@ -128,7 +117,7 @@ static int perf_record__mmap_read(struct perf_record *rec, | |||
| 128 | size = md->mask + 1 - (old & md->mask); | 117 | size = md->mask + 1 - (old & md->mask); |
| 129 | old += size; | 118 | old += size; |
| 130 | 119 | ||
| 131 | if (perf_record__write(rec, buf, size) < 0) { | 120 | if (record__write(rec, buf, size) < 0) { |
| 132 | rc = -1; | 121 | rc = -1; |
| 133 | goto out; | 122 | goto out; |
| 134 | } | 123 | } |
| @@ -138,7 +127,7 @@ static int perf_record__mmap_read(struct perf_record *rec, | |||
| 138 | size = head - old; | 127 | size = head - old; |
| 139 | old += size; | 128 | old += size; |
| 140 | 129 | ||
| 141 | if (perf_record__write(rec, buf, size) < 0) { | 130 | if (record__write(rec, buf, size) < 0) { |
| 142 | rc = -1; | 131 | rc = -1; |
| 143 | goto out; | 132 | goto out; |
| 144 | } | 133 | } |
| @@ -163,9 +152,9 @@ static void sig_handler(int sig) | |||
| 163 | signr = sig; | 152 | signr = sig; |
| 164 | } | 153 | } |
| 165 | 154 | ||
| 166 | static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) | 155 | static void record__sig_exit(int exit_status __maybe_unused, void *arg) |
| 167 | { | 156 | { |
| 168 | struct perf_record *rec = arg; | 157 | struct record *rec = arg; |
| 169 | int status; | 158 | int status; |
| 170 | 159 | ||
| 171 | if (rec->evlist->workload.pid > 0) { | 160 | if (rec->evlist->workload.pid > 0) { |
| @@ -183,13 +172,13 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) | |||
| 183 | signal(signr, SIG_DFL); | 172 | signal(signr, SIG_DFL); |
| 184 | } | 173 | } |
| 185 | 174 | ||
| 186 | static int perf_record__open(struct perf_record *rec) | 175 | static int record__open(struct record *rec) |
| 187 | { | 176 | { |
| 188 | char msg[512]; | 177 | char msg[512]; |
| 189 | struct perf_evsel *pos; | 178 | struct perf_evsel *pos; |
| 190 | struct perf_evlist *evlist = rec->evlist; | 179 | struct perf_evlist *evlist = rec->evlist; |
| 191 | struct perf_session *session = rec->session; | 180 | struct perf_session *session = rec->session; |
| 192 | struct perf_record_opts *opts = &rec->opts; | 181 | struct record_opts *opts = &rec->opts; |
| 193 | int rc = 0; | 182 | int rc = 0; |
| 194 | 183 | ||
| 195 | perf_evlist__config(evlist, opts); | 184 | perf_evlist__config(evlist, opts); |
| @@ -239,7 +228,7 @@ out: | |||
| 239 | return rc; | 228 | return rc; |
| 240 | } | 229 | } |
| 241 | 230 | ||
| 242 | static int process_buildids(struct perf_record *rec) | 231 | static int process_buildids(struct record *rec) |
| 243 | { | 232 | { |
| 244 | struct perf_data_file *file = &rec->file; | 233 | struct perf_data_file *file = &rec->file; |
| 245 | struct perf_session *session = rec->session; | 234 | struct perf_session *session = rec->session; |
| @@ -254,9 +243,9 @@ static int process_buildids(struct perf_record *rec) | |||
| 254 | size, &build_id__mark_dso_hit_ops); | 243 | size, &build_id__mark_dso_hit_ops); |
| 255 | } | 244 | } |
| 256 | 245 | ||
| 257 | static void perf_record__exit(int status, void *arg) | 246 | static void record__exit(int status, void *arg) |
| 258 | { | 247 | { |
| 259 | struct perf_record *rec = arg; | 248 | struct record *rec = arg; |
| 260 | struct perf_data_file *file = &rec->file; | 249 | struct perf_data_file *file = &rec->file; |
| 261 | 250 | ||
| 262 | if (status != 0) | 251 | if (status != 0) |
| @@ -312,14 +301,14 @@ static struct perf_event_header finished_round_event = { | |||
| 312 | .type = PERF_RECORD_FINISHED_ROUND, | 301 | .type = PERF_RECORD_FINISHED_ROUND, |
| 313 | }; | 302 | }; |
| 314 | 303 | ||
| 315 | static int perf_record__mmap_read_all(struct perf_record *rec) | 304 | static int record__mmap_read_all(struct record *rec) |
| 316 | { | 305 | { |
| 317 | int i; | 306 | int i; |
| 318 | int rc = 0; | 307 | int rc = 0; |
| 319 | 308 | ||
| 320 | for (i = 0; i < rec->evlist->nr_mmaps; i++) { | 309 | for (i = 0; i < rec->evlist->nr_mmaps; i++) { |
| 321 | if (rec->evlist->mmap[i].base) { | 310 | if (rec->evlist->mmap[i].base) { |
| 322 | if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { | 311 | if (record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { |
| 323 | rc = -1; | 312 | rc = -1; |
| 324 | goto out; | 313 | goto out; |
| 325 | } | 314 | } |
| @@ -327,14 +316,13 @@ static int perf_record__mmap_read_all(struct perf_record *rec) | |||
| 327 | } | 316 | } |
| 328 | 317 | ||
| 329 | if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) | 318 | if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) |
| 330 | rc = perf_record__write(rec, &finished_round_event, | 319 | rc = record__write(rec, &finished_round_event, sizeof(finished_round_event)); |
| 331 | sizeof(finished_round_event)); | ||
| 332 | 320 | ||
| 333 | out: | 321 | out: |
| 334 | return rc; | 322 | return rc; |
| 335 | } | 323 | } |
| 336 | 324 | ||
| 337 | static void perf_record__init_features(struct perf_record *rec) | 325 | static void record__init_features(struct record *rec) |
| 338 | { | 326 | { |
| 339 | struct perf_evlist *evsel_list = rec->evlist; | 327 | struct perf_evlist *evsel_list = rec->evlist; |
| 340 | struct perf_session *session = rec->session; | 328 | struct perf_session *session = rec->session; |
| @@ -353,14 +341,14 @@ static void perf_record__init_features(struct perf_record *rec) | |||
| 353 | perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); | 341 | perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); |
| 354 | } | 342 | } |
| 355 | 343 | ||
| 356 | static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | 344 | static int __cmd_record(struct record *rec, int argc, const char **argv) |
| 357 | { | 345 | { |
| 358 | int err; | 346 | int err; |
| 359 | unsigned long waking = 0; | 347 | unsigned long waking = 0; |
| 360 | const bool forks = argc > 0; | 348 | const bool forks = argc > 0; |
| 361 | struct machine *machine; | 349 | struct machine *machine; |
| 362 | struct perf_tool *tool = &rec->tool; | 350 | struct perf_tool *tool = &rec->tool; |
| 363 | struct perf_record_opts *opts = &rec->opts; | 351 | struct record_opts *opts = &rec->opts; |
| 364 | struct perf_evlist *evsel_list = rec->evlist; | 352 | struct perf_evlist *evsel_list = rec->evlist; |
| 365 | struct perf_data_file *file = &rec->file; | 353 | struct perf_data_file *file = &rec->file; |
| 366 | struct perf_session *session; | 354 | struct perf_session *session; |
| @@ -368,7 +356,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 368 | 356 | ||
| 369 | rec->progname = argv[0]; | 357 | rec->progname = argv[0]; |
| 370 | 358 | ||
| 371 | on_exit(perf_record__sig_exit, rec); | 359 | on_exit(record__sig_exit, rec); |
| 372 | signal(SIGCHLD, sig_handler); | 360 | signal(SIGCHLD, sig_handler); |
| 373 | signal(SIGINT, sig_handler); | 361 | signal(SIGINT, sig_handler); |
| 374 | signal(SIGUSR1, sig_handler); | 362 | signal(SIGUSR1, sig_handler); |
| @@ -382,7 +370,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 382 | 370 | ||
| 383 | rec->session = session; | 371 | rec->session = session; |
| 384 | 372 | ||
| 385 | perf_record__init_features(rec); | 373 | record__init_features(rec); |
| 386 | 374 | ||
| 387 | if (forks) { | 375 | if (forks) { |
| 388 | err = perf_evlist__prepare_workload(evsel_list, &opts->target, | 376 | err = perf_evlist__prepare_workload(evsel_list, &opts->target, |
| @@ -394,7 +382,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 394 | } | 382 | } |
| 395 | } | 383 | } |
| 396 | 384 | ||
| 397 | if (perf_record__open(rec) != 0) { | 385 | if (record__open(rec) != 0) { |
| 398 | err = -1; | 386 | err = -1; |
| 399 | goto out_delete_session; | 387 | goto out_delete_session; |
| 400 | } | 388 | } |
| @@ -403,9 +391,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 403 | perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); | 391 | perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); |
| 404 | 392 | ||
| 405 | /* | 393 | /* |
| 406 | * perf_session__delete(session) will be called at perf_record__exit() | 394 | * perf_session__delete(session) will be called at record__exit() |
| 407 | */ | 395 | */ |
| 408 | on_exit(perf_record__exit, rec); | 396 | on_exit(record__exit, rec); |
| 409 | 397 | ||
| 410 | if (file->is_pipe) { | 398 | if (file->is_pipe) { |
| 411 | err = perf_header__write_pipe(file->fd); | 399 | err = perf_header__write_pipe(file->fd); |
| @@ -510,7 +498,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 510 | for (;;) { | 498 | for (;;) { |
| 511 | int hits = rec->samples; | 499 | int hits = rec->samples; |
| 512 | 500 | ||
| 513 | if (perf_record__mmap_read_all(rec) < 0) { | 501 | if (record__mmap_read_all(rec) < 0) { |
| 514 | err = -1; | 502 | err = -1; |
| 515 | goto out_delete_session; | 503 | goto out_delete_session; |
| 516 | } | 504 | } |
| @@ -669,7 +657,7 @@ static int get_stack_size(char *str, unsigned long *_size) | |||
| 669 | } | 657 | } |
| 670 | #endif /* HAVE_LIBUNWIND_SUPPORT */ | 658 | #endif /* HAVE_LIBUNWIND_SUPPORT */ |
| 671 | 659 | ||
| 672 | int record_parse_callchain(const char *arg, struct perf_record_opts *opts) | 660 | int record_parse_callchain(const char *arg, struct record_opts *opts) |
| 673 | { | 661 | { |
| 674 | char *tok, *name, *saveptr = NULL; | 662 | char *tok, *name, *saveptr = NULL; |
| 675 | char *buf; | 663 | char *buf; |
| @@ -725,7 +713,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts) | |||
| 725 | return ret; | 713 | return ret; |
| 726 | } | 714 | } |
| 727 | 715 | ||
| 728 | static void callchain_debug(struct perf_record_opts *opts) | 716 | static void callchain_debug(struct record_opts *opts) |
| 729 | { | 717 | { |
| 730 | pr_debug("callchain: type %d\n", opts->call_graph); | 718 | pr_debug("callchain: type %d\n", opts->call_graph); |
| 731 | 719 | ||
| @@ -738,7 +726,7 @@ int record_parse_callchain_opt(const struct option *opt, | |||
| 738 | const char *arg, | 726 | const char *arg, |
| 739 | int unset) | 727 | int unset) |
| 740 | { | 728 | { |
| 741 | struct perf_record_opts *opts = opt->value; | 729 | struct record_opts *opts = opt->value; |
| 742 | int ret; | 730 | int ret; |
| 743 | 731 | ||
| 744 | /* --no-call-graph */ | 732 | /* --no-call-graph */ |
| @@ -759,7 +747,7 @@ int record_callchain_opt(const struct option *opt, | |||
| 759 | const char *arg __maybe_unused, | 747 | const char *arg __maybe_unused, |
| 760 | int unset __maybe_unused) | 748 | int unset __maybe_unused) |
| 761 | { | 749 | { |
| 762 | struct perf_record_opts *opts = opt->value; | 750 | struct record_opts *opts = opt->value; |
| 763 | 751 | ||
| 764 | if (opts->call_graph == CALLCHAIN_NONE) | 752 | if (opts->call_graph == CALLCHAIN_NONE) |
| 765 | opts->call_graph = CALLCHAIN_FP; | 753 | opts->call_graph = CALLCHAIN_FP; |
| @@ -775,8 +763,8 @@ static const char * const record_usage[] = { | |||
| 775 | }; | 763 | }; |
| 776 | 764 | ||
| 777 | /* | 765 | /* |
| 778 | * XXX Ideally would be local to cmd_record() and passed to a perf_record__new | 766 | * XXX Ideally would be local to cmd_record() and passed to a record__new |
| 779 | * because we need to have access to it in perf_record__exit, that is called | 767 | * because we need to have access to it in record__exit, that is called |
| 780 | * after cmd_record() exits, but since record_options need to be accessible to | 768 | * after cmd_record() exits, but since record_options need to be accessible to |
| 781 | * builtin-script, leave it here. | 769 | * builtin-script, leave it here. |
| 782 | * | 770 | * |
| @@ -784,7 +772,7 @@ static const char * const record_usage[] = { | |||
| 784 | * | 772 | * |
| 785 | * Just say no to tons of global variables, sigh. | 773 | * Just say no to tons of global variables, sigh. |
| 786 | */ | 774 | */ |
| 787 | static struct perf_record record = { | 775 | static struct record record = { |
| 788 | .opts = { | 776 | .opts = { |
| 789 | .mmap_pages = UINT_MAX, | 777 | .mmap_pages = UINT_MAX, |
| 790 | .user_freq = UINT_MAX, | 778 | .user_freq = UINT_MAX, |
| @@ -808,7 +796,7 @@ const char record_callchain_help[] = CALLCHAIN_HELP "fp"; | |||
| 808 | /* | 796 | /* |
| 809 | * XXX Will stay a global variable till we fix builtin-script.c to stop messing | 797 | * XXX Will stay a global variable till we fix builtin-script.c to stop messing |
| 810 | * with it and switch to use the library functions in perf_evlist that came | 798 | * with it and switch to use the library functions in perf_evlist that came |
| 811 | * from builtin-record.c, i.e. use perf_record_opts, | 799 | * from builtin-record.c, i.e. use record_opts, |
| 812 | * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', | 800 | * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', |
| 813 | * using pipes, etc. | 801 | * using pipes, etc. |
| 814 | */ | 802 | */ |
| @@ -891,7 +879,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 891 | { | 879 | { |
| 892 | int err = -ENOMEM; | 880 | int err = -ENOMEM; |
| 893 | struct perf_evlist *evsel_list; | 881 | struct perf_evlist *evsel_list; |
| 894 | struct perf_record *rec = &record; | 882 | struct record *rec = &record; |
| 895 | char errbuf[BUFSIZ]; | 883 | char errbuf[BUFSIZ]; |
| 896 | 884 | ||
| 897 | evsel_list = perf_evlist__new(); | 885 | evsel_list = perf_evlist__new(); |
| @@ -956,7 +944,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 956 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) | 944 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) |
| 957 | usage_with_options(record_usage, record_options); | 945 | usage_with_options(record_usage, record_options); |
| 958 | 946 | ||
| 959 | if (perf_record_opts__config(&rec->opts)) { | 947 | if (record_opts__config(&rec->opts)) { |
| 960 | err = -EINVAL; | 948 | err = -EINVAL; |
| 961 | goto out_free_fd; | 949 | goto out_free_fd; |
| 962 | } | 950 | } |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3a14dbed387c..bf8dd2e893e4 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | #include <dlfcn.h> | 39 | #include <dlfcn.h> |
| 40 | #include <linux/bitmap.h> | 40 | #include <linux/bitmap.h> |
| 41 | 41 | ||
| 42 | struct perf_report { | 42 | struct report { |
| 43 | struct perf_tool tool; | 43 | struct perf_tool tool; |
| 44 | struct perf_session *session; | 44 | struct perf_session *session; |
| 45 | bool force, use_tui, use_gtk, use_stdio; | 45 | bool force, use_tui, use_gtk, use_stdio; |
| @@ -60,14 +60,14 @@ struct perf_report { | |||
| 60 | DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); | 60 | DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static int perf_report_config(const char *var, const char *value, void *cb) | 63 | static int report__config(const char *var, const char *value, void *cb) |
| 64 | { | 64 | { |
| 65 | if (!strcmp(var, "report.group")) { | 65 | if (!strcmp(var, "report.group")) { |
| 66 | symbol_conf.event_group = perf_config_bool(var, value); | 66 | symbol_conf.event_group = perf_config_bool(var, value); |
| 67 | return 0; | 67 | return 0; |
| 68 | } | 68 | } |
| 69 | if (!strcmp(var, "report.percent-limit")) { | 69 | if (!strcmp(var, "report.percent-limit")) { |
| 70 | struct perf_report *rep = cb; | 70 | struct report *rep = cb; |
| 71 | rep->min_percent = strtof(value, NULL); | 71 | rep->min_percent = strtof(value, NULL); |
| 72 | return 0; | 72 | return 0; |
| 73 | } | 73 | } |
| @@ -75,31 +75,40 @@ static int perf_report_config(const char *var, const char *value, void *cb) | |||
| 75 | return perf_default_config(var, value, cb); | 75 | return perf_default_config(var, value, cb); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static int perf_report__add_mem_hist_entry(struct perf_tool *tool, | 78 | static int report__resolve_callchain(struct report *rep, struct symbol **parent, |
| 79 | struct addr_location *al, | 79 | struct perf_evsel *evsel, struct addr_location *al, |
| 80 | struct perf_sample *sample, | 80 | struct perf_sample *sample) |
| 81 | struct perf_evsel *evsel, | ||
| 82 | struct machine *machine, | ||
| 83 | union perf_event *event) | ||
| 84 | { | 81 | { |
| 85 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 82 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { |
| 83 | return machine__resolve_callchain(al->machine, evsel, al->thread, sample, | ||
| 84 | parent, al, rep->max_stack); | ||
| 85 | } | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample) | ||
| 90 | { | ||
| 91 | if (!symbol_conf.use_callchain) | ||
| 92 | return 0; | ||
| 93 | return callchain_append(he->callchain, &callchain_cursor, sample->period); | ||
| 94 | } | ||
| 95 | |||
| 96 | static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_location *al, | ||
| 97 | struct perf_sample *sample, struct perf_evsel *evsel, | ||
| 98 | union perf_event *event) | ||
| 99 | { | ||
| 100 | struct report *rep = container_of(tool, struct report, tool); | ||
| 86 | struct symbol *parent = NULL; | 101 | struct symbol *parent = NULL; |
| 87 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 102 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
| 88 | int err = 0; | ||
| 89 | struct hist_entry *he; | 103 | struct hist_entry *he; |
| 90 | struct mem_info *mi, *mx; | 104 | struct mem_info *mi, *mx; |
| 91 | uint64_t cost; | 105 | uint64_t cost; |
| 106 | int err = report__resolve_callchain(rep, &parent, evsel, al, sample); | ||
| 92 | 107 | ||
| 93 | if ((sort__has_parent || symbol_conf.use_callchain) && | 108 | if (err) |
| 94 | sample->callchain) { | 109 | return err; |
| 95 | err = machine__resolve_callchain(machine, evsel, al->thread, | ||
| 96 | sample, &parent, al, | ||
| 97 | rep->max_stack); | ||
| 98 | if (err) | ||
| 99 | return err; | ||
| 100 | } | ||
| 101 | 110 | ||
| 102 | mi = machine__resolve_mem(machine, al->thread, sample, cpumode); | 111 | mi = machine__resolve_mem(al->machine, al->thread, sample, cpumode); |
| 103 | if (!mi) | 112 | if (!mi) |
| 104 | return -ENOMEM; | 113 | return -ENOMEM; |
| 105 | 114 | ||
| @@ -122,77 +131,36 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool, | |||
| 122 | if (!he) | 131 | if (!he) |
| 123 | return -ENOMEM; | 132 | return -ENOMEM; |
| 124 | 133 | ||
| 125 | /* | 134 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
| 126 | * In the TUI browser, we are doing integrated annotation, | 135 | if (err) |
| 127 | * so we don't allocate the extra space needed because the stdio | 136 | goto out; |
| 128 | * code will not use it. | ||
| 129 | */ | ||
| 130 | if (sort__has_sym && he->ms.sym && use_browser > 0) { | ||
| 131 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
| 132 | |||
| 133 | assert(evsel != NULL); | ||
| 134 | |||
| 135 | if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0) | ||
| 136 | goto out; | ||
| 137 | |||
| 138 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
| 139 | if (err) | ||
| 140 | goto out; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (sort__has_sym && he->mem_info->daddr.sym && use_browser > 0) { | ||
| 144 | struct annotation *notes; | ||
| 145 | |||
| 146 | mx = he->mem_info; | ||
| 147 | 137 | ||
| 148 | notes = symbol__annotation(mx->daddr.sym); | 138 | mx = he->mem_info; |
| 149 | if (notes->src == NULL && symbol__alloc_hist(mx->daddr.sym) < 0) | 139 | err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx); |
| 150 | goto out; | 140 | if (err) |
| 151 | 141 | goto out; | |
| 152 | err = symbol__inc_addr_samples(mx->daddr.sym, | ||
| 153 | mx->daddr.map, | ||
| 154 | evsel->idx, | ||
| 155 | mx->daddr.al_addr); | ||
| 156 | if (err) | ||
| 157 | goto out; | ||
| 158 | } | ||
| 159 | 142 | ||
| 160 | evsel->hists.stats.total_period += cost; | 143 | evsel->hists.stats.total_period += cost; |
| 161 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 144 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
| 162 | err = 0; | 145 | err = hist_entry__append_callchain(he, sample); |
| 163 | |||
| 164 | if (symbol_conf.use_callchain) { | ||
| 165 | err = callchain_append(he->callchain, | ||
| 166 | &callchain_cursor, | ||
| 167 | sample->period); | ||
| 168 | } | ||
| 169 | out: | 146 | out: |
| 170 | return err; | 147 | return err; |
| 171 | } | 148 | } |
| 172 | 149 | ||
| 173 | static int perf_report__add_branch_hist_entry(struct perf_tool *tool, | 150 | static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_location *al, |
| 174 | struct addr_location *al, | 151 | struct perf_sample *sample, struct perf_evsel *evsel) |
| 175 | struct perf_sample *sample, | ||
| 176 | struct perf_evsel *evsel, | ||
| 177 | struct machine *machine) | ||
| 178 | { | 152 | { |
| 179 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 153 | struct report *rep = container_of(tool, struct report, tool); |
| 180 | struct symbol *parent = NULL; | 154 | struct symbol *parent = NULL; |
| 181 | int err = 0; | ||
| 182 | unsigned i; | 155 | unsigned i; |
| 183 | struct hist_entry *he; | 156 | struct hist_entry *he; |
| 184 | struct branch_info *bi, *bx; | 157 | struct branch_info *bi, *bx; |
| 158 | int err = report__resolve_callchain(rep, &parent, evsel, al, sample); | ||
| 185 | 159 | ||
| 186 | if ((sort__has_parent || symbol_conf.use_callchain) | 160 | if (err) |
| 187 | && sample->callchain) { | 161 | return err; |
| 188 | err = machine__resolve_callchain(machine, evsel, al->thread, | ||
| 189 | sample, &parent, al, | ||
| 190 | rep->max_stack); | ||
| 191 | if (err) | ||
| 192 | return err; | ||
| 193 | } | ||
| 194 | 162 | ||
| 195 | bi = machine__resolve_bstack(machine, al->thread, | 163 | bi = machine__resolve_bstack(al->machine, al->thread, |
| 196 | sample->branch_stack); | 164 | sample->branch_stack); |
| 197 | if (!bi) | 165 | if (!bi) |
| 198 | return -ENOMEM; | 166 | return -ENOMEM; |
| @@ -214,35 +182,15 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, | |||
| 214 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, | 182 | he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL, |
| 215 | 1, 1, 0); | 183 | 1, 1, 0); |
| 216 | if (he) { | 184 | if (he) { |
| 217 | struct annotation *notes; | ||
| 218 | bx = he->branch_info; | 185 | bx = he->branch_info; |
| 219 | if (bx->from.sym && use_browser == 1 && sort__has_sym) { | 186 | err = addr_map_symbol__inc_samples(&bx->from, evsel->idx); |
| 220 | notes = symbol__annotation(bx->from.sym); | 187 | if (err) |
| 221 | if (!notes->src | 188 | goto out; |
| 222 | && symbol__alloc_hist(bx->from.sym) < 0) | 189 | |
| 223 | goto out; | 190 | err = addr_map_symbol__inc_samples(&bx->to, evsel->idx); |
| 224 | 191 | if (err) | |
| 225 | err = symbol__inc_addr_samples(bx->from.sym, | 192 | goto out; |
| 226 | bx->from.map, | ||
| 227 | evsel->idx, | ||
| 228 | bx->from.al_addr); | ||
| 229 | if (err) | ||
| 230 | goto out; | ||
| 231 | } | ||
| 232 | 193 | ||
| 233 | if (bx->to.sym && use_browser == 1 && sort__has_sym) { | ||
| 234 | notes = symbol__annotation(bx->to.sym); | ||
| 235 | if (!notes->src | ||
| 236 | && symbol__alloc_hist(bx->to.sym) < 0) | ||
| 237 | goto out; | ||
| 238 | |||
| 239 | err = symbol__inc_addr_samples(bx->to.sym, | ||
| 240 | bx->to.map, | ||
| 241 | evsel->idx, | ||
| 242 | bx->to.al_addr); | ||
| 243 | if (err) | ||
| 244 | goto out; | ||
| 245 | } | ||
| 246 | evsel->hists.stats.total_period += 1; | 194 | evsel->hists.stats.total_period += 1; |
| 247 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 195 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
| 248 | } else | 196 | } else |
| @@ -254,24 +202,16 @@ out: | |||
| 254 | return err; | 202 | return err; |
| 255 | } | 203 | } |
| 256 | 204 | ||
| 257 | static int perf_evsel__add_hist_entry(struct perf_tool *tool, | 205 | static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evsel, |
| 258 | struct perf_evsel *evsel, | 206 | struct addr_location *al, struct perf_sample *sample) |
| 259 | struct addr_location *al, | ||
| 260 | struct perf_sample *sample, | ||
| 261 | struct machine *machine) | ||
| 262 | { | 207 | { |
| 263 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 208 | struct report *rep = container_of(tool, struct report, tool); |
| 264 | struct symbol *parent = NULL; | 209 | struct symbol *parent = NULL; |
| 265 | int err = 0; | ||
| 266 | struct hist_entry *he; | 210 | struct hist_entry *he; |
| 211 | int err = report__resolve_callchain(rep, &parent, evsel, al, sample); | ||
| 267 | 212 | ||
| 268 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { | 213 | if (err) |
| 269 | err = machine__resolve_callchain(machine, evsel, al->thread, | 214 | return err; |
| 270 | sample, &parent, al, | ||
| 271 | rep->max_stack); | ||
| 272 | if (err) | ||
| 273 | return err; | ||
| 274 | } | ||
| 275 | 215 | ||
| 276 | he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL, | 216 | he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL, |
| 277 | sample->period, sample->weight, | 217 | sample->period, sample->weight, |
| @@ -279,30 +219,11 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool, | |||
| 279 | if (he == NULL) | 219 | if (he == NULL) |
| 280 | return -ENOMEM; | 220 | return -ENOMEM; |
| 281 | 221 | ||
| 282 | if (symbol_conf.use_callchain) { | 222 | err = hist_entry__append_callchain(he, sample); |
| 283 | err = callchain_append(he->callchain, | 223 | if (err) |
| 284 | &callchain_cursor, | 224 | goto out; |
| 285 | sample->period); | ||
| 286 | if (err) | ||
| 287 | return err; | ||
| 288 | } | ||
| 289 | /* | ||
| 290 | * Only in the TUI browser we are doing integrated annotation, | ||
| 291 | * so we don't allocated the extra space needed because the stdio | ||
| 292 | * code will not use it. | ||
| 293 | */ | ||
| 294 | if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) { | ||
| 295 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
| 296 | |||
| 297 | assert(evsel != NULL); | ||
| 298 | |||
| 299 | err = -ENOMEM; | ||
| 300 | if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0) | ||
| 301 | goto out; | ||
| 302 | |||
| 303 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
| 304 | } | ||
| 305 | 225 | ||
| 226 | err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | ||
| 306 | evsel->hists.stats.total_period += sample->period; | 227 | evsel->hists.stats.total_period += sample->period; |
| 307 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 228 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
| 308 | out: | 229 | out: |
| @@ -316,13 +237,13 @@ static int process_sample_event(struct perf_tool *tool, | |||
| 316 | struct perf_evsel *evsel, | 237 | struct perf_evsel *evsel, |
| 317 | struct machine *machine) | 238 | struct machine *machine) |
| 318 | { | 239 | { |
| 319 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 240 | struct report *rep = container_of(tool, struct report, tool); |
| 320 | struct addr_location al; | 241 | struct addr_location al; |
| 321 | int ret; | 242 | int ret; |
| 322 | 243 | ||
| 323 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { | 244 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { |
| 324 | fprintf(stderr, "problem processing %d event, skipping it.\n", | 245 | pr_debug("problem processing %d event, skipping it.\n", |
| 325 | event->header.type); | 246 | event->header.type); |
| 326 | return -1; | 247 | return -1; |
| 327 | } | 248 | } |
| 328 | 249 | ||
| @@ -333,21 +254,18 @@ static int process_sample_event(struct perf_tool *tool, | |||
| 333 | return 0; | 254 | return 0; |
| 334 | 255 | ||
| 335 | if (sort__mode == SORT_MODE__BRANCH) { | 256 | if (sort__mode == SORT_MODE__BRANCH) { |
| 336 | ret = perf_report__add_branch_hist_entry(tool, &al, sample, | 257 | ret = report__add_branch_hist_entry(tool, &al, sample, evsel); |
| 337 | evsel, machine); | ||
| 338 | if (ret < 0) | 258 | if (ret < 0) |
| 339 | pr_debug("problem adding lbr entry, skipping event\n"); | 259 | pr_debug("problem adding lbr entry, skipping event\n"); |
| 340 | } else if (rep->mem_mode == 1) { | 260 | } else if (rep->mem_mode == 1) { |
| 341 | ret = perf_report__add_mem_hist_entry(tool, &al, sample, | 261 | ret = report__add_mem_hist_entry(tool, &al, sample, evsel, event); |
| 342 | evsel, machine, event); | ||
| 343 | if (ret < 0) | 262 | if (ret < 0) |
| 344 | pr_debug("problem adding mem entry, skipping event\n"); | 263 | pr_debug("problem adding mem entry, skipping event\n"); |
| 345 | } else { | 264 | } else { |
| 346 | if (al.map != NULL) | 265 | if (al.map != NULL) |
| 347 | al.map->dso->hit = 1; | 266 | al.map->dso->hit = 1; |
| 348 | 267 | ||
| 349 | ret = perf_evsel__add_hist_entry(tool, evsel, &al, sample, | 268 | ret = report__add_hist_entry(tool, evsel, &al, sample); |
| 350 | machine); | ||
| 351 | if (ret < 0) | 269 | if (ret < 0) |
| 352 | pr_debug("problem incrementing symbol period, skipping event\n"); | 270 | pr_debug("problem incrementing symbol period, skipping event\n"); |
| 353 | } | 271 | } |
| @@ -360,7 +278,7 @@ static int process_read_event(struct perf_tool *tool, | |||
| 360 | struct perf_evsel *evsel, | 278 | struct perf_evsel *evsel, |
| 361 | struct machine *machine __maybe_unused) | 279 | struct machine *machine __maybe_unused) |
| 362 | { | 280 | { |
| 363 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 281 | struct report *rep = container_of(tool, struct report, tool); |
| 364 | 282 | ||
| 365 | if (rep->show_threads) { | 283 | if (rep->show_threads) { |
| 366 | const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; | 284 | const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; |
| @@ -379,7 +297,7 @@ static int process_read_event(struct perf_tool *tool, | |||
| 379 | } | 297 | } |
| 380 | 298 | ||
| 381 | /* For pipe mode, sample_type is not currently set */ | 299 | /* For pipe mode, sample_type is not currently set */ |
| 382 | static int perf_report__setup_sample_type(struct perf_report *rep) | 300 | static int report__setup_sample_type(struct report *rep) |
| 383 | { | 301 | { |
| 384 | struct perf_session *session = rep->session; | 302 | struct perf_session *session = rep->session; |
| 385 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); | 303 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); |
| @@ -424,8 +342,7 @@ static void sig_handler(int sig __maybe_unused) | |||
| 424 | session_done = 1; | 342 | session_done = 1; |
| 425 | } | 343 | } |
| 426 | 344 | ||
| 427 | static size_t hists__fprintf_nr_sample_events(struct perf_report *rep, | 345 | static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep, |
| 428 | struct hists *hists, | ||
| 429 | const char *evname, FILE *fp) | 346 | const char *evname, FILE *fp) |
| 430 | { | 347 | { |
| 431 | size_t ret; | 348 | size_t ret; |
| @@ -462,7 +379,7 @@ static size_t hists__fprintf_nr_sample_events(struct perf_report *rep, | |||
| 462 | } | 379 | } |
| 463 | 380 | ||
| 464 | static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | 381 | static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, |
| 465 | struct perf_report *rep, | 382 | struct report *rep, |
| 466 | const char *help) | 383 | const char *help) |
| 467 | { | 384 | { |
| 468 | struct perf_evsel *pos; | 385 | struct perf_evsel *pos; |
| @@ -475,7 +392,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
| 475 | !perf_evsel__is_group_leader(pos)) | 392 | !perf_evsel__is_group_leader(pos)) |
| 476 | continue; | 393 | continue; |
| 477 | 394 | ||
| 478 | hists__fprintf_nr_sample_events(rep, hists, evname, stdout); | 395 | hists__fprintf_nr_sample_events(hists, rep, evname, stdout); |
| 479 | hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout); | 396 | hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout); |
| 480 | fprintf(stdout, "\n\n"); | 397 | fprintf(stdout, "\n\n"); |
| 481 | } | 398 | } |
| @@ -495,7 +412,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
| 495 | return 0; | 412 | return 0; |
| 496 | } | 413 | } |
| 497 | 414 | ||
| 498 | static int __cmd_report(struct perf_report *rep) | 415 | static int __cmd_report(struct report *rep) |
| 499 | { | 416 | { |
| 500 | int ret = -EINVAL; | 417 | int ret = -EINVAL; |
| 501 | u64 nr_samples; | 418 | u64 nr_samples; |
| @@ -519,7 +436,7 @@ static int __cmd_report(struct perf_report *rep) | |||
| 519 | if (rep->show_threads) | 436 | if (rep->show_threads) |
| 520 | perf_read_values_init(&rep->show_threads_values); | 437 | perf_read_values_init(&rep->show_threads_values); |
| 521 | 438 | ||
| 522 | ret = perf_report__setup_sample_type(rep); | 439 | ret = report__setup_sample_type(rep); |
| 523 | if (ret) | 440 | if (ret) |
| 524 | return ret; | 441 | return ret; |
| 525 | 442 | ||
| @@ -552,15 +469,17 @@ static int __cmd_report(struct perf_report *rep) | |||
| 552 | desc); | 469 | desc); |
| 553 | } | 470 | } |
| 554 | 471 | ||
| 555 | if (verbose > 3) | 472 | if (use_browser == 0) { |
| 556 | perf_session__fprintf(session, stdout); | 473 | if (verbose > 3) |
| 474 | perf_session__fprintf(session, stdout); | ||
| 557 | 475 | ||
| 558 | if (verbose > 2) | 476 | if (verbose > 2) |
| 559 | perf_session__fprintf_dsos(session, stdout); | 477 | perf_session__fprintf_dsos(session, stdout); |
| 560 | 478 | ||
| 561 | if (dump_trace) { | 479 | if (dump_trace) { |
| 562 | perf_session__fprintf_nr_events(session, stdout); | 480 | perf_session__fprintf_nr_events(session, stdout); |
| 563 | return 0; | 481 | return 0; |
| 482 | } | ||
| 564 | } | 483 | } |
| 565 | 484 | ||
| 566 | nr_samples = 0; | 485 | nr_samples = 0; |
| @@ -638,7 +557,7 @@ static int __cmd_report(struct perf_report *rep) | |||
| 638 | static int | 557 | static int |
| 639 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) | 558 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) |
| 640 | { | 559 | { |
| 641 | struct perf_report *rep = (struct perf_report *)opt->value; | 560 | struct report *rep = (struct report *)opt->value; |
| 642 | char *tok, *tok2; | 561 | char *tok, *tok2; |
| 643 | char *endptr; | 562 | char *endptr; |
| 644 | 563 | ||
| @@ -720,7 +639,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) | |||
| 720 | return -1; | 639 | return -1; |
| 721 | setup: | 640 | setup: |
| 722 | if (callchain_register_param(&callchain_param) < 0) { | 641 | if (callchain_register_param(&callchain_param) < 0) { |
| 723 | fprintf(stderr, "Can't register callchain params\n"); | 642 | pr_err("Can't register callchain params\n"); |
| 724 | return -1; | 643 | return -1; |
| 725 | } | 644 | } |
| 726 | return 0; | 645 | return 0; |
| @@ -758,7 +677,7 @@ static int | |||
| 758 | parse_percent_limit(const struct option *opt, const char *str, | 677 | parse_percent_limit(const struct option *opt, const char *str, |
| 759 | int unset __maybe_unused) | 678 | int unset __maybe_unused) |
| 760 | { | 679 | { |
| 761 | struct perf_report *rep = opt->value; | 680 | struct report *rep = opt->value; |
| 762 | 681 | ||
| 763 | rep->min_percent = strtof(str, NULL); | 682 | rep->min_percent = strtof(str, NULL); |
| 764 | return 0; | 683 | return 0; |
| @@ -776,7 +695,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 776 | "perf report [<options>]", | 695 | "perf report [<options>]", |
| 777 | NULL | 696 | NULL |
| 778 | }; | 697 | }; |
| 779 | struct perf_report report = { | 698 | struct report report = { |
| 780 | .tool = { | 699 | .tool = { |
| 781 | .sample = process_sample_event, | 700 | .sample = process_sample_event, |
| 782 | .mmap = perf_event__process_mmap, | 701 | .mmap = perf_event__process_mmap, |
| @@ -892,7 +811,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 892 | .mode = PERF_DATA_MODE_READ, | 811 | .mode = PERF_DATA_MODE_READ, |
| 893 | }; | 812 | }; |
| 894 | 813 | ||
| 895 | perf_config(perf_report_config, &report); | 814 | perf_config(report__config, &report); |
| 896 | 815 | ||
| 897 | argc = parse_options(argc, argv, options, report_usage, 0); | 816 | argc = parse_options(argc, argv, options, report_usage, 0); |
| 898 | 817 | ||
| @@ -942,7 +861,7 @@ repeat: | |||
| 942 | } | 861 | } |
| 943 | if (report.mem_mode) { | 862 | if (report.mem_mode) { |
| 944 | if (sort__mode == SORT_MODE__BRANCH) { | 863 | if (sort__mode == SORT_MODE__BRANCH) { |
| 945 | fprintf(stderr, "branch and mem mode incompatible\n"); | 864 | pr_err("branch and mem mode incompatible\n"); |
| 946 | goto error; | 865 | goto error; |
| 947 | } | 866 | } |
| 948 | sort__mode = SORT_MODE__MEMORY; | 867 | sort__mode = SORT_MODE__MEMORY; |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 0f3c65518a2c..6a76a07b6789 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
| @@ -469,7 +469,7 @@ static void *thread_func(void *ctx) | |||
| 469 | char comm2[22]; | 469 | char comm2[22]; |
| 470 | int fd; | 470 | int fd; |
| 471 | 471 | ||
| 472 | free(parms); | 472 | zfree(&parms); |
| 473 | 473 | ||
| 474 | sprintf(comm2, ":%s", this_task->comm); | 474 | sprintf(comm2, ":%s", this_task->comm); |
| 475 | prctl(PR_SET_NAME, comm2); | 475 | prctl(PR_SET_NAME, comm2); |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f8ab125aac48..6040000bdfa6 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -423,7 +423,6 @@ static void print_sample_addr(union perf_event *event, | |||
| 423 | static void print_sample_bts(union perf_event *event, | 423 | static void print_sample_bts(union perf_event *event, |
| 424 | struct perf_sample *sample, | 424 | struct perf_sample *sample, |
| 425 | struct perf_evsel *evsel, | 425 | struct perf_evsel *evsel, |
| 426 | struct machine *machine, | ||
| 427 | struct thread *thread, | 426 | struct thread *thread, |
| 428 | struct addr_location *al) | 427 | struct addr_location *al) |
| 429 | { | 428 | { |
| @@ -435,7 +434,7 @@ static void print_sample_bts(union perf_event *event, | |||
| 435 | printf(" "); | 434 | printf(" "); |
| 436 | else | 435 | else |
| 437 | printf("\n"); | 436 | printf("\n"); |
| 438 | perf_evsel__print_ip(evsel, sample, machine, al, | 437 | perf_evsel__print_ip(evsel, sample, al, |
| 439 | output[attr->type].print_ip_opts, | 438 | output[attr->type].print_ip_opts, |
| 440 | PERF_MAX_STACK_DEPTH); | 439 | PERF_MAX_STACK_DEPTH); |
| 441 | } | 440 | } |
| @@ -446,14 +445,13 @@ static void print_sample_bts(union perf_event *event, | |||
| 446 | if (PRINT_FIELD(ADDR) || | 445 | if (PRINT_FIELD(ADDR) || |
| 447 | ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && | 446 | ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && |
| 448 | !output[attr->type].user_set)) | 447 | !output[attr->type].user_set)) |
| 449 | print_sample_addr(event, sample, machine, thread, attr); | 448 | print_sample_addr(event, sample, al->machine, thread, attr); |
| 450 | 449 | ||
| 451 | printf("\n"); | 450 | printf("\n"); |
| 452 | } | 451 | } |
| 453 | 452 | ||
| 454 | static void process_event(union perf_event *event, struct perf_sample *sample, | 453 | static void process_event(union perf_event *event, struct perf_sample *sample, |
| 455 | struct perf_evsel *evsel, struct machine *machine, | 454 | struct perf_evsel *evsel, struct thread *thread, |
| 456 | struct thread *thread, | ||
| 457 | struct addr_location *al) | 455 | struct addr_location *al) |
| 458 | { | 456 | { |
| 459 | struct perf_event_attr *attr = &evsel->attr; | 457 | struct perf_event_attr *attr = &evsel->attr; |
| @@ -469,7 +467,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
| 469 | } | 467 | } |
| 470 | 468 | ||
| 471 | if (is_bts_event(attr)) { | 469 | if (is_bts_event(attr)) { |
| 472 | print_sample_bts(event, sample, evsel, machine, thread, al); | 470 | print_sample_bts(event, sample, evsel, thread, al); |
| 473 | return; | 471 | return; |
| 474 | } | 472 | } |
| 475 | 473 | ||
| @@ -477,7 +475,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
| 477 | event_format__print(evsel->tp_format, sample->cpu, | 475 | event_format__print(evsel->tp_format, sample->cpu, |
| 478 | sample->raw_data, sample->raw_size); | 476 | sample->raw_data, sample->raw_size); |
| 479 | if (PRINT_FIELD(ADDR)) | 477 | if (PRINT_FIELD(ADDR)) |
| 480 | print_sample_addr(event, sample, machine, thread, attr); | 478 | print_sample_addr(event, sample, al->machine, thread, attr); |
| 481 | 479 | ||
| 482 | if (PRINT_FIELD(IP)) { | 480 | if (PRINT_FIELD(IP)) { |
| 483 | if (!symbol_conf.use_callchain) | 481 | if (!symbol_conf.use_callchain) |
| @@ -485,7 +483,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
| 485 | else | 483 | else |
| 486 | printf("\n"); | 484 | printf("\n"); |
| 487 | 485 | ||
| 488 | perf_evsel__print_ip(evsel, sample, machine, al, | 486 | perf_evsel__print_ip(evsel, sample, al, |
| 489 | output[attr->type].print_ip_opts, | 487 | output[attr->type].print_ip_opts, |
| 490 | PERF_MAX_STACK_DEPTH); | 488 | PERF_MAX_STACK_DEPTH); |
| 491 | } | 489 | } |
| @@ -574,7 +572,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
| 574 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) | 572 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) |
| 575 | return 0; | 573 | return 0; |
| 576 | 574 | ||
| 577 | scripting_ops->process_event(event, sample, evsel, machine, thread, &al); | 575 | scripting_ops->process_event(event, sample, evsel, thread, &al); |
| 578 | 576 | ||
| 579 | evsel->hists.stats.total_period += sample->period; | 577 | evsel->hists.stats.total_period += sample->period; |
| 580 | return 0; | 578 | return 0; |
| @@ -1104,9 +1102,9 @@ static struct script_desc *script_desc__new(const char *name) | |||
| 1104 | 1102 | ||
| 1105 | static void script_desc__delete(struct script_desc *s) | 1103 | static void script_desc__delete(struct script_desc *s) |
| 1106 | { | 1104 | { |
| 1107 | free(s->name); | 1105 | zfree(&s->name); |
| 1108 | free(s->half_liner); | 1106 | zfree(&s->half_liner); |
| 1109 | free(s->args); | 1107 | zfree(&s->args); |
| 1110 | free(s); | 1108 | free(s); |
| 1111 | } | 1109 | } |
| 1112 | 1110 | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index dab98b50c9fe..106a5e5b7842 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -185,8 +185,7 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) | |||
| 185 | 185 | ||
| 186 | static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) | 186 | static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) |
| 187 | { | 187 | { |
| 188 | free(evsel->priv); | 188 | zfree(&evsel->priv); |
| 189 | evsel->priv = NULL; | ||
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) | 191 | static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) |
| @@ -208,8 +207,7 @@ static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) | |||
| 208 | 207 | ||
| 209 | static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) | 208 | static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) |
| 210 | { | 209 | { |
| 211 | free(evsel->prev_raw_counts); | 210 | zfree(&evsel->prev_raw_counts); |
| 212 | evsel->prev_raw_counts = NULL; | ||
| 213 | } | 211 | } |
| 214 | 212 | ||
| 215 | static void perf_evlist__free_stats(struct perf_evlist *evlist) | 213 | static void perf_evlist__free_stats(struct perf_evlist *evlist) |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 20d4212fa337..652af0b66a62 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
| @@ -488,8 +488,7 @@ static const char *cat_backtrace(union perf_event *event, | |||
| 488 | * It seems the callchain is corrupted. | 488 | * It seems the callchain is corrupted. |
| 489 | * Discard all. | 489 | * Discard all. |
| 490 | */ | 490 | */ |
| 491 | free(p); | 491 | zfree(&p); |
| 492 | p = NULL; | ||
| 493 | goto exit; | 492 | goto exit; |
| 494 | } | 493 | } |
| 495 | continue; | 494 | continue; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 03d37a76c612..172e91a9ce62 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -189,21 +189,18 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
| 189 | if (pthread_mutex_trylock(¬es->lock)) | 189 | if (pthread_mutex_trylock(¬es->lock)) |
| 190 | return; | 190 | return; |
| 191 | 191 | ||
| 192 | if (notes->src == NULL && symbol__alloc_hist(sym) < 0) { | ||
| 193 | pthread_mutex_unlock(¬es->lock); | ||
| 194 | pr_err("Not enough memory for annotating '%s' symbol!\n", | ||
| 195 | sym->name); | ||
| 196 | sleep(1); | ||
| 197 | return; | ||
| 198 | } | ||
| 199 | |||
| 200 | ip = he->ms.map->map_ip(he->ms.map, ip); | 192 | ip = he->ms.map->map_ip(he->ms.map, ip); |
| 201 | err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); | 193 | err = hist_entry__inc_addr_samples(he, counter, ip); |
| 202 | 194 | ||
| 203 | pthread_mutex_unlock(¬es->lock); | 195 | pthread_mutex_unlock(¬es->lock); |
| 204 | 196 | ||
| 205 | if (err == -ERANGE && !he->ms.map->erange_warned) | 197 | if (err == -ERANGE && !he->ms.map->erange_warned) |
| 206 | ui__warn_map_erange(he->ms.map, sym, ip); | 198 | ui__warn_map_erange(he->ms.map, sym, ip); |
| 199 | else if (err == -ENOMEM) { | ||
| 200 | pr_err("Not enough memory for annotating '%s' symbol!\n", | ||
| 201 | sym->name); | ||
| 202 | sleep(1); | ||
| 203 | } | ||
| 207 | } | 204 | } |
| 208 | 205 | ||
| 209 | static void perf_top__show_details(struct perf_top *top) | 206 | static void perf_top__show_details(struct perf_top *top) |
| @@ -857,7 +854,7 @@ static int perf_top__start_counters(struct perf_top *top) | |||
| 857 | char msg[512]; | 854 | char msg[512]; |
| 858 | struct perf_evsel *counter; | 855 | struct perf_evsel *counter; |
| 859 | struct perf_evlist *evlist = top->evlist; | 856 | struct perf_evlist *evlist = top->evlist; |
| 860 | struct perf_record_opts *opts = &top->record_opts; | 857 | struct record_opts *opts = &top->record_opts; |
| 861 | 858 | ||
| 862 | perf_evlist__config(evlist, opts); | 859 | perf_evlist__config(evlist, opts); |
| 863 | 860 | ||
| @@ -909,7 +906,7 @@ static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused) | |||
| 909 | 906 | ||
| 910 | static int __cmd_top(struct perf_top *top) | 907 | static int __cmd_top(struct perf_top *top) |
| 911 | { | 908 | { |
| 912 | struct perf_record_opts *opts = &top->record_opts; | 909 | struct record_opts *opts = &top->record_opts; |
| 913 | pthread_t thread; | 910 | pthread_t thread; |
| 914 | int ret; | 911 | int ret; |
| 915 | 912 | ||
| @@ -1031,7 +1028,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1031 | .max_stack = PERF_MAX_STACK_DEPTH, | 1028 | .max_stack = PERF_MAX_STACK_DEPTH, |
| 1032 | .sym_pcnt_filter = 5, | 1029 | .sym_pcnt_filter = 5, |
| 1033 | }; | 1030 | }; |
| 1034 | struct perf_record_opts *opts = &top.record_opts; | 1031 | struct record_opts *opts = &top.record_opts; |
| 1035 | struct target *target = &opts->target; | 1032 | struct target *target = &opts->target; |
| 1036 | const struct option options[] = { | 1033 | const struct option options[] = { |
| 1037 | OPT_CALLBACK('e', "event", &top.evlist, "event", | 1034 | OPT_CALLBACK('e', "event", &top.evlist, "event", |
| @@ -1182,7 +1179,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1182 | if (top.delay_secs < 1) | 1179 | if (top.delay_secs < 1) |
| 1183 | top.delay_secs = 1; | 1180 | top.delay_secs = 1; |
| 1184 | 1181 | ||
| 1185 | if (perf_record_opts__config(opts)) { | 1182 | if (record_opts__config(opts)) { |
| 1186 | status = -EINVAL; | 1183 | status = -EINVAL; |
| 1187 | goto out_delete_maps; | 1184 | goto out_delete_maps; |
| 1188 | } | 1185 | } |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 56bbca5bc2dc..c5b4bc51175c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -146,8 +146,7 @@ static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel, | |||
| 146 | 146 | ||
| 147 | static void perf_evsel__delete_priv(struct perf_evsel *evsel) | 147 | static void perf_evsel__delete_priv(struct perf_evsel *evsel) |
| 148 | { | 148 | { |
| 149 | free(evsel->priv); | 149 | zfree(&evsel->priv); |
| 150 | evsel->priv = NULL; | ||
| 151 | perf_evsel__delete(evsel); | 150 | perf_evsel__delete(evsel); |
| 152 | } | 151 | } |
| 153 | 152 | ||
| @@ -165,8 +164,7 @@ static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler) | |||
| 165 | return -ENOMEM; | 164 | return -ENOMEM; |
| 166 | 165 | ||
| 167 | out_delete: | 166 | out_delete: |
| 168 | free(evsel->priv); | 167 | zfree(&evsel->priv); |
| 169 | evsel->priv = NULL; | ||
| 170 | return -ENOENT; | 168 | return -ENOENT; |
| 171 | } | 169 | } |
| 172 | 170 | ||
| @@ -1159,7 +1157,7 @@ struct trace { | |||
| 1159 | int max; | 1157 | int max; |
| 1160 | struct syscall *table; | 1158 | struct syscall *table; |
| 1161 | } syscalls; | 1159 | } syscalls; |
| 1162 | struct perf_record_opts opts; | 1160 | struct record_opts opts; |
| 1163 | struct machine *host; | 1161 | struct machine *host; |
| 1164 | u64 base_time; | 1162 | u64 base_time; |
| 1165 | bool full_time; | 1163 | bool full_time; |
| @@ -1278,10 +1276,8 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, | |||
| 1278 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); | 1276 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); |
| 1279 | struct thread_trace *ttrace = arg->thread->priv; | 1277 | struct thread_trace *ttrace = arg->thread->priv; |
| 1280 | 1278 | ||
| 1281 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) { | 1279 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) |
| 1282 | free(ttrace->paths.table[fd]); | 1280 | zfree(&ttrace->paths.table[fd]); |
| 1283 | ttrace->paths.table[fd] = NULL; | ||
| 1284 | } | ||
| 1285 | 1281 | ||
| 1286 | return printed; | 1282 | return printed; |
| 1287 | } | 1283 | } |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5a1f4df3c3a8..14faeeb0d752 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
| @@ -126,7 +126,7 @@ endif | |||
| 126 | 126 | ||
| 127 | feature_check = $(eval $(feature_check_code)) | 127 | feature_check = $(eval $(feature_check_code)) |
| 128 | define feature_check_code | 128 | define feature_check_code |
| 129 | feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) | 129 | feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) |
| 130 | endef | 130 | endef |
| 131 | 131 | ||
| 132 | feature_set = $(eval $(feature_set_code)) | 132 | feature_set = $(eval $(feature_set_code)) |
| @@ -173,7 +173,7 @@ CORE_FEATURE_TESTS = \ | |||
| 173 | # to skip the print-out of the long features list if the file | 173 | # to skip the print-out of the long features list if the file |
| 174 | # existed before and after it was built: | 174 | # existed before and after it was built: |
| 175 | # | 175 | # |
| 176 | ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),) | 176 | ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all.bin),) |
| 177 | test-all-failed := 1 | 177 | test-all-failed := 1 |
| 178 | else | 178 | else |
| 179 | test-all-failed := 0 | 179 | test-all-failed := 0 |
| @@ -203,7 +203,7 @@ ifeq ($(feature-all), 1) | |||
| 203 | # | 203 | # |
| 204 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) | 204 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) |
| 205 | else | 205 | else |
| 206 | $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) | 206 | $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(CORE_FEATURE_TESTS)) >/dev/null 2>&1) |
| 207 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) | 207 | $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) |
| 208 | endif | 208 | endif |
| 209 | 209 | ||
diff --git a/tools/perf/config/feature-checks/.gitignore b/tools/perf/config/feature-checks/.gitignore new file mode 100644 index 000000000000..80f3da0c3515 --- /dev/null +++ b/tools/perf/config/feature-checks/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | *.d | ||
| 2 | *.bin | ||
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index bc86462e80a2..7cf6fcdacebe 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile | |||
| @@ -1,90 +1,90 @@ | |||
| 1 | 1 | ||
| 2 | FILES= \ | 2 | FILES= \ |
| 3 | test-all \ | 3 | test-all.bin \ |
| 4 | test-backtrace \ | 4 | test-backtrace.bin \ |
| 5 | test-bionic \ | 5 | test-bionic.bin \ |
| 6 | test-dwarf \ | 6 | test-dwarf.bin \ |
| 7 | test-fortify-source \ | 7 | test-fortify-source.bin \ |
| 8 | test-glibc \ | 8 | test-glibc.bin \ |
| 9 | test-gtk2 \ | 9 | test-gtk2.bin \ |
| 10 | test-gtk2-infobar \ | 10 | test-gtk2-infobar.bin \ |
| 11 | test-hello \ | 11 | test-hello.bin \ |
| 12 | test-libaudit \ | 12 | test-libaudit.bin \ |
| 13 | test-libbfd \ | 13 | test-libbfd.bin \ |
| 14 | test-liberty \ | 14 | test-liberty.bin \ |
| 15 | test-liberty-z \ | 15 | test-liberty-z.bin \ |
| 16 | test-cplus-demangle \ | 16 | test-cplus-demangle.bin \ |
| 17 | test-libelf \ | 17 | test-libelf.bin \ |
| 18 | test-libelf-getphdrnum \ | 18 | test-libelf-getphdrnum.bin \ |
| 19 | test-libelf-mmap \ | 19 | test-libelf-mmap.bin \ |
| 20 | test-libnuma \ | 20 | test-libnuma.bin \ |
| 21 | test-libperl \ | 21 | test-libperl.bin \ |
| 22 | test-libpython \ | 22 | test-libpython.bin \ |
| 23 | test-libpython-version \ | 23 | test-libpython-version.bin \ |
| 24 | test-libslang \ | 24 | test-libslang.bin \ |
| 25 | test-libunwind \ | 25 | test-libunwind.bin \ |
| 26 | test-libunwind-debug-frame \ | 26 | test-libunwind-debug-frame.bin \ |
| 27 | test-on-exit \ | 27 | test-on-exit.bin \ |
| 28 | test-stackprotector-all \ | 28 | test-stackprotector-all.bin \ |
| 29 | test-timerfd | 29 | test-timerfd.bin |
| 30 | 30 | ||
| 31 | CC := $(CC) -MD | 31 | CC := $(CC) -MD |
| 32 | 32 | ||
| 33 | all: $(FILES) | 33 | all: $(FILES) |
| 34 | 34 | ||
| 35 | BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $@.c $(LDFLAGS) | 35 | BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS) |
| 36 | 36 | ||
| 37 | ############################### | 37 | ############################### |
| 38 | 38 | ||
| 39 | test-all: | 39 | test-all.bin: |
| 40 | $(BUILD) -Werror -fstack-protector-all -O2 -Werror -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 | 40 | $(BUILD) -Werror -fstack-protector-all -O2 -Werror -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 |
| 41 | 41 | ||
| 42 | test-hello: | 42 | test-hello.bin: |
| 43 | $(BUILD) | 43 | $(BUILD) |
| 44 | 44 | ||
| 45 | test-stackprotector-all: | 45 | test-stackprotector-all.bin: |
| 46 | $(BUILD) -Werror -fstack-protector-all | 46 | $(BUILD) -Werror -fstack-protector-all |
| 47 | 47 | ||
| 48 | test-fortify-source: | 48 | test-fortify-source.bin: |
| 49 | $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 | 49 | $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 |
| 50 | 50 | ||
| 51 | test-bionic: | 51 | test-bionic.bin: |
| 52 | $(BUILD) | 52 | $(BUILD) |
| 53 | 53 | ||
| 54 | test-libelf: | 54 | test-libelf.bin: |
| 55 | $(BUILD) -lelf | 55 | $(BUILD) -lelf |
| 56 | 56 | ||
| 57 | test-glibc: | 57 | test-glibc.bin: |
| 58 | $(BUILD) | 58 | $(BUILD) |
| 59 | 59 | ||
| 60 | test-dwarf: | 60 | test-dwarf.bin: |
| 61 | $(BUILD) -ldw | 61 | $(BUILD) -ldw |
| 62 | 62 | ||
| 63 | test-libelf-mmap: | 63 | test-libelf-mmap.bin: |
| 64 | $(BUILD) -lelf | 64 | $(BUILD) -lelf |
| 65 | 65 | ||
| 66 | test-libelf-getphdrnum: | 66 | test-libelf-getphdrnum.bin: |
| 67 | $(BUILD) -lelf | 67 | $(BUILD) -lelf |
| 68 | 68 | ||
| 69 | test-libnuma: | 69 | test-libnuma.bin: |
| 70 | $(BUILD) -lnuma | 70 | $(BUILD) -lnuma |
| 71 | 71 | ||
| 72 | test-libunwind: | 72 | test-libunwind.bin: |
| 73 | $(BUILD) -lelf | 73 | $(BUILD) -lelf |
| 74 | 74 | ||
| 75 | test-libunwind-debug-frame: | 75 | test-libunwind-debug-frame.bin: |
| 76 | $(BUILD) -lelf | 76 | $(BUILD) -lelf |
| 77 | 77 | ||
| 78 | test-libaudit: | 78 | test-libaudit.bin: |
| 79 | $(BUILD) -laudit | 79 | $(BUILD) -laudit |
| 80 | 80 | ||
| 81 | test-libslang: | 81 | test-libslang.bin: |
| 82 | $(BUILD) -I/usr/include/slang -lslang | 82 | $(BUILD) -I/usr/include/slang -lslang |
| 83 | 83 | ||
| 84 | test-gtk2: | 84 | test-gtk2.bin: |
| 85 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) | 85 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) |
| 86 | 86 | ||
| 87 | test-gtk2-infobar: | 87 | test-gtk2-infobar.bin: |
| 88 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) | 88 | $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) |
| 89 | 89 | ||
| 90 | grep-libs = $(filter -l%,$(1)) | 90 | grep-libs = $(filter -l%,$(1)) |
| @@ -96,7 +96,7 @@ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) | |||
| 96 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` | 96 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` |
| 97 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) | 97 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) |
| 98 | 98 | ||
| 99 | test-libperl: | 99 | test-libperl.bin: |
| 100 | $(BUILD) $(FLAGS_PERL_EMBED) | 100 | $(BUILD) $(FLAGS_PERL_EMBED) |
| 101 | 101 | ||
| 102 | override PYTHON := python | 102 | override PYTHON := python |
| @@ -113,31 +113,31 @@ PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) | |||
| 113 | PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) | 113 | PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) |
| 114 | FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) | 114 | FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) |
| 115 | 115 | ||
| 116 | test-libpython: | 116 | test-libpython.bin: |
| 117 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 117 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
| 118 | 118 | ||
| 119 | test-libpython-version: | 119 | test-libpython-version.bin: |
| 120 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 120 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
| 121 | 121 | ||
| 122 | test-libbfd: | 122 | test-libbfd.bin: |
| 123 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl | 123 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl |
| 124 | 124 | ||
| 125 | test-liberty: | 125 | test-liberty.bin: |
| 126 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty | 126 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty |
| 127 | 127 | ||
| 128 | test-liberty-z: | 128 | test-liberty-z.bin: |
| 129 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz | 129 | $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz |
| 130 | 130 | ||
| 131 | test-cplus-demangle: | 131 | test-cplus-demangle.bin: |
| 132 | $(BUILD) -liberty | 132 | $(BUILD) -liberty |
| 133 | 133 | ||
| 134 | test-on-exit: | 134 | test-on-exit.bin: |
| 135 | $(BUILD) | 135 | $(BUILD) |
| 136 | 136 | ||
| 137 | test-backtrace: | 137 | test-backtrace.bin: |
| 138 | $(BUILD) | 138 | $(BUILD) |
| 139 | 139 | ||
| 140 | test-timerfd: | 140 | test-timerfd.bin: |
| 141 | $(BUILD) | 141 | $(BUILD) |
| 142 | 142 | ||
| 143 | -include *.d | 143 | -include *.d |
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index f168debc5be2..4d985e0f03f5 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak | |||
| @@ -178,10 +178,3 @@ endef | |||
| 178 | _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) | 178 | _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) |
| 179 | _gea_warn = $(warning The path '$(1)' is not executable.) | 179 | _gea_warn = $(warning The path '$(1)' is not executable.) |
| 180 | _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) | 180 | _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) |
| 181 | |||
| 182 | ifneq ($(findstring $(MAKEFLAGS),s),s) | ||
| 183 | ifneq ($(V),1) | ||
| 184 | QUIET_CLEAN = @printf ' CLEAN %s\n' $1; | ||
| 185 | QUIET_INSTALL = @printf ' INSTALL %s\n' $1; | ||
| 186 | endif | ||
| 187 | endif | ||
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index b23fed527514..b1cc84b01d5b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
| @@ -247,7 +247,7 @@ enum perf_call_graph_mode { | |||
| 247 | CALLCHAIN_DWARF | 247 | CALLCHAIN_DWARF |
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | struct perf_record_opts { | 250 | struct record_opts { |
| 251 | struct target target; | 251 | struct target target; |
| 252 | int call_graph; | 252 | int call_graph; |
| 253 | bool group; | 253 | bool group; |
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 85d4919dd623..4248d1e96848 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c | |||
| @@ -391,7 +391,7 @@ static int do_test_code_reading(bool try_kcore) | |||
| 391 | struct machines machines; | 391 | struct machines machines; |
| 392 | struct machine *machine; | 392 | struct machine *machine; |
| 393 | struct thread *thread; | 393 | struct thread *thread; |
| 394 | struct perf_record_opts opts = { | 394 | struct record_opts opts = { |
| 395 | .mmap_pages = UINT_MAX, | 395 | .mmap_pages = UINT_MAX, |
| 396 | .user_freq = UINT_MAX, | 396 | .user_freq = UINT_MAX, |
| 397 | .user_interval = ULLONG_MAX, | 397 | .user_interval = ULLONG_MAX, |
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 376c35608534..27eb75142b88 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c | |||
| @@ -51,7 +51,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm) | |||
| 51 | */ | 51 | */ |
| 52 | int test__keep_tracking(void) | 52 | int test__keep_tracking(void) |
| 53 | { | 53 | { |
| 54 | struct perf_record_opts opts = { | 54 | struct record_opts opts = { |
| 55 | .mmap_pages = UINT_MAX, | 55 | .mmap_pages = UINT_MAX, |
| 56 | .user_freq = UINT_MAX, | 56 | .user_freq = UINT_MAX, |
| 57 | .user_interval = ULLONG_MAX, | 57 | .user_interval = ULLONG_MAX, |
diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 2ca0abf1b2b6..f641c35f2321 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make | |||
| @@ -106,10 +106,36 @@ test_make_python_perf_so := test -f $(PERF)/python/perf.so | |||
| 106 | test_make_perf_o := test -f $(PERF)/perf.o | 106 | test_make_perf_o := test -f $(PERF)/perf.o |
| 107 | test_make_util_map_o := test -f $(PERF)/util/map.o | 107 | test_make_util_map_o := test -f $(PERF)/util/map.o |
| 108 | 108 | ||
| 109 | test_make_install := test -x $$TMP_DEST/bin/perf | 109 | define test_dest_files |
| 110 | test_make_install_O := $(test_make_install) | 110 | for file in $(1); do \ |
| 111 | test_make_install_bin := $(test_make_install) | 111 | if [ ! -x $$TMP_DEST/$$file ]; then \ |
| 112 | test_make_install_bin_O := $(test_make_install) | 112 | echo " failed to find: $$file"; \ |
| 113 | fi \ | ||
| 114 | done | ||
| 115 | endef | ||
| 116 | |||
| 117 | installed_files_bin := bin/perf | ||
| 118 | installed_files_bin += etc/bash_completion.d/perf | ||
| 119 | installed_files_bin += libexec/perf-core/perf-archive | ||
| 120 | |||
| 121 | installed_files_plugins := lib64/traceevent/plugins/plugin_cfg80211.so | ||
| 122 | installed_files_plugins += lib64/traceevent/plugins/plugin_scsi.so | ||
| 123 | installed_files_plugins += lib64/traceevent/plugins/plugin_xen.so | ||
| 124 | installed_files_plugins += lib64/traceevent/plugins/plugin_function.so | ||
| 125 | installed_files_plugins += lib64/traceevent/plugins/plugin_sched_switch.so | ||
| 126 | installed_files_plugins += lib64/traceevent/plugins/plugin_mac80211.so | ||
| 127 | installed_files_plugins += lib64/traceevent/plugins/plugin_kvm.so | ||
| 128 | installed_files_plugins += lib64/traceevent/plugins/plugin_kmem.so | ||
| 129 | installed_files_plugins += lib64/traceevent/plugins/plugin_hrtimer.so | ||
| 130 | installed_files_plugins += lib64/traceevent/plugins/plugin_jbd2.so | ||
| 131 | |||
| 132 | installed_files_all := $(installed_files_bin) | ||
| 133 | installed_files_all += $(installed_files_plugins) | ||
| 134 | |||
| 135 | test_make_install := $(call test_dest_files,$(installed_files_all)) | ||
| 136 | test_make_install_O := $(call test_dest_files,$(installed_files_all)) | ||
| 137 | test_make_install_bin := $(call test_dest_files,$(installed_files_bin)) | ||
| 138 | test_make_install_bin_O := $(call test_dest_files,$(installed_files_bin)) | ||
| 113 | 139 | ||
| 114 | # FIXME nothing gets installed | 140 | # FIXME nothing gets installed |
| 115 | test_make_install_man := test -f $$TMP_DEST/share/man/man1/perf.1 | 141 | test_make_install_man := test -f $$TMP_DEST/share/man/man1/perf.1 |
| @@ -162,7 +188,7 @@ $(run): | |||
| 162 | cmd="cd $(PERF) && make -f $(MK) DESTDIR=$$TMP_DEST $($@)"; \ | 188 | cmd="cd $(PERF) && make -f $(MK) DESTDIR=$$TMP_DEST $($@)"; \ |
| 163 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ | 189 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ |
| 164 | ( eval $$cmd ) >> $@ 2>&1; \ | 190 | ( eval $$cmd ) >> $@ 2>&1; \ |
| 165 | echo " test: $(call test,$@)"; \ | 191 | echo " test: $(call test,$@)" >> $@ 2>&1; \ |
| 166 | $(call test,$@) && \ | 192 | $(call test,$@) && \ |
| 167 | rm -f $@ \ | 193 | rm -f $@ \ |
| 168 | rm -rf $$TMP_DEST | 194 | rm -rf $$TMP_DEST |
| @@ -174,7 +200,7 @@ $(run_O): | |||
| 174 | cmd="cd $(PERF) && make -f $(MK) O=$$TMP_O DESTDIR=$$TMP_DEST $($(patsubst %_O,%,$@))"; \ | 200 | cmd="cd $(PERF) && make -f $(MK) O=$$TMP_O DESTDIR=$$TMP_DEST $($(patsubst %_O,%,$@))"; \ |
| 175 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ | 201 | echo "- $@: $$cmd" && echo $$cmd > $@ && \ |
| 176 | ( eval $$cmd ) >> $@ 2>&1 && \ | 202 | ( eval $$cmd ) >> $@ 2>&1 && \ |
| 177 | echo " test: $(call test_O,$@)"; \ | 203 | echo " test: $(call test_O,$@)" >> $@ 2>&1; \ |
| 178 | $(call test_O,$@) && \ | 204 | $(call test_O,$@) && \ |
| 179 | rm -f $@ && \ | 205 | rm -f $@ && \ |
| 180 | rm -rf $$TMP_O \ | 206 | rm -rf $$TMP_O \ |
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 41cc0badb74b..774620a5aecb 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | int test__syscall_open_tp_fields(void) | 7 | int test__syscall_open_tp_fields(void) |
| 8 | { | 8 | { |
| 9 | struct perf_record_opts opts = { | 9 | struct record_opts opts = { |
| 10 | .target = { | 10 | .target = { |
| 11 | .uid = UINT_MAX, | 11 | .uid = UINT_MAX, |
| 12 | .uses_mmap = true, | 12 | .uses_mmap = true, |
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 93a62b06c3af..eeba562920e9 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c | |||
| @@ -34,7 +34,7 @@ realloc: | |||
| 34 | 34 | ||
| 35 | int test__PERF_RECORD(void) | 35 | int test__PERF_RECORD(void) |
| 36 | { | 36 | { |
| 37 | struct perf_record_opts opts = { | 37 | struct record_opts opts = { |
| 38 | .target = { | 38 | .target = { |
| 39 | .uid = UINT_MAX, | 39 | .uid = UINT_MAX, |
| 40 | .uses_mmap = true, | 40 | .uses_mmap = true, |
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index 4ca1b938f6a6..c6398b90e897 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c | |||
| @@ -46,7 +46,7 @@ static u64 rdtsc(void) | |||
| 46 | */ | 46 | */ |
| 47 | int test__perf_time_to_tsc(void) | 47 | int test__perf_time_to_tsc(void) |
| 48 | { | 48 | { |
| 49 | struct perf_record_opts opts = { | 49 | struct record_opts opts = { |
| 50 | .mmap_pages = UINT_MAX, | 50 | .mmap_pages = UINT_MAX, |
| 51 | .user_freq = UINT_MAX, | 51 | .user_freq = UINT_MAX, |
| 52 | .user_interval = ULLONG_MAX, | 52 | .user_interval = ULLONG_MAX, |
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index cbaa7af45513..d11541d4d7d7 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c | |||
| @@ -256,8 +256,7 @@ int ui_browser__show(struct ui_browser *browser, const char *title, | |||
| 256 | __ui_browser__show_title(browser, title); | 256 | __ui_browser__show_title(browser, title); |
| 257 | 257 | ||
| 258 | browser->title = title; | 258 | browser->title = title; |
| 259 | free(browser->helpline); | 259 | zfree(&browser->helpline); |
| 260 | browser->helpline = NULL; | ||
| 261 | 260 | ||
| 262 | va_start(ap, helpline); | 261 | va_start(ap, helpline); |
| 263 | err = vasprintf(&browser->helpline, helpline, ap); | 262 | err = vasprintf(&browser->helpline, helpline, ap); |
| @@ -268,12 +267,11 @@ int ui_browser__show(struct ui_browser *browser, const char *title, | |||
| 268 | return err ? 0 : -1; | 267 | return err ? 0 : -1; |
| 269 | } | 268 | } |
| 270 | 269 | ||
| 271 | void ui_browser__hide(struct ui_browser *browser __maybe_unused) | 270 | void ui_browser__hide(struct ui_browser *browser) |
| 272 | { | 271 | { |
| 273 | pthread_mutex_lock(&ui__lock); | 272 | pthread_mutex_lock(&ui__lock); |
| 274 | ui_helpline__pop(); | 273 | ui_helpline__pop(); |
| 275 | free(browser->helpline); | 274 | zfree(&browser->helpline); |
| 276 | browser->helpline = NULL; | ||
| 277 | pthread_mutex_unlock(&ui__lock); | 275 | pthread_mutex_unlock(&ui__lock); |
| 278 | } | 276 | } |
| 279 | 277 | ||
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index 7d45d2f53601..118cca29dd26 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h | |||
| @@ -59,6 +59,8 @@ int ui_browser__help_window(struct ui_browser *browser, const char *text); | |||
| 59 | bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); | 59 | bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); |
| 60 | int ui_browser__input_window(const char *title, const char *text, char *input, | 60 | int ui_browser__input_window(const char *title, const char *text, char *input, |
| 61 | const char *exit_msg, int delay_sec); | 61 | const char *exit_msg, int delay_sec); |
| 62 | struct perf_session_env; | ||
| 63 | int tui__header_window(struct perf_session_env *env); | ||
| 62 | 64 | ||
| 63 | void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); | 65 | void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); |
| 64 | unsigned int ui_browser__argv_refresh(struct ui_browser *browser); | 66 | unsigned int ui_browser__argv_refresh(struct ui_browser *browser); |
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c new file mode 100644 index 000000000000..89c16b988618 --- /dev/null +++ b/tools/perf/ui/browsers/header.c | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | #include "util/cache.h" | ||
| 2 | #include "util/debug.h" | ||
| 3 | #include "ui/browser.h" | ||
| 4 | #include "ui/ui.h" | ||
| 5 | #include "ui/util.h" | ||
| 6 | #include "ui/libslang.h" | ||
| 7 | #include "util/header.h" | ||
| 8 | #include "util/session.h" | ||
| 9 | |||
| 10 | static void ui_browser__argv_write(struct ui_browser *browser, | ||
| 11 | void *entry, int row) | ||
| 12 | { | ||
| 13 | char **arg = entry; | ||
| 14 | char *str = *arg; | ||
| 15 | char empty[] = " "; | ||
| 16 | bool current_entry = ui_browser__is_current_entry(browser, row); | ||
| 17 | unsigned long offset = (unsigned long)browser->priv; | ||
| 18 | |||
| 19 | if (offset >= strlen(str)) | ||
| 20 | str = empty; | ||
| 21 | else | ||
| 22 | str = str + offset; | ||
| 23 | |||
| 24 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : | ||
| 25 | HE_COLORSET_NORMAL); | ||
| 26 | |||
| 27 | slsmg_write_nstring(str, browser->width); | ||
| 28 | } | ||
| 29 | |||
| 30 | static int list_menu__run(struct ui_browser *menu) | ||
| 31 | { | ||
| 32 | int key; | ||
| 33 | unsigned long offset; | ||
| 34 | const char help[] = | ||
| 35 | "h/?/F1 Show this window\n" | ||
| 36 | "UP/DOWN/PGUP\n" | ||
| 37 | "PGDN/SPACE\n" | ||
| 38 | "LEFT/RIGHT Navigate\n" | ||
| 39 | "q/ESC/CTRL+C Exit browser"; | ||
| 40 | |||
| 41 | if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0) | ||
| 42 | return -1; | ||
| 43 | |||
| 44 | while (1) { | ||
| 45 | key = ui_browser__run(menu, 0); | ||
| 46 | |||
| 47 | switch (key) { | ||
| 48 | case K_RIGHT: | ||
| 49 | offset = (unsigned long)menu->priv; | ||
| 50 | offset += 10; | ||
| 51 | menu->priv = (void *)offset; | ||
| 52 | continue; | ||
| 53 | case K_LEFT: | ||
| 54 | offset = (unsigned long)menu->priv; | ||
| 55 | if (offset >= 10) | ||
| 56 | offset -= 10; | ||
| 57 | menu->priv = (void *)offset; | ||
| 58 | continue; | ||
| 59 | case K_F1: | ||
| 60 | case 'h': | ||
| 61 | case '?': | ||
| 62 | ui_browser__help_window(menu, help); | ||
| 63 | continue; | ||
| 64 | case K_ESC: | ||
| 65 | case 'q': | ||
| 66 | case CTRL('c'): | ||
| 67 | key = -1; | ||
| 68 | break; | ||
| 69 | default: | ||
| 70 | continue; | ||
| 71 | } | ||
| 72 | |||
| 73 | break; | ||
| 74 | } | ||
| 75 | |||
| 76 | ui_browser__hide(menu); | ||
| 77 | return key; | ||
| 78 | } | ||
| 79 | |||
| 80 | static int ui__list_menu(int argc, char * const argv[]) | ||
| 81 | { | ||
| 82 | struct ui_browser menu = { | ||
| 83 | .entries = (void *)argv, | ||
| 84 | .refresh = ui_browser__argv_refresh, | ||
| 85 | .seek = ui_browser__argv_seek, | ||
| 86 | .write = ui_browser__argv_write, | ||
| 87 | .nr_entries = argc, | ||
| 88 | }; | ||
| 89 | |||
| 90 | return list_menu__run(&menu); | ||
| 91 | } | ||
| 92 | |||
| 93 | int tui__header_window(struct perf_session_env *env) | ||
| 94 | { | ||
| 95 | int i, argc = 0; | ||
| 96 | char **argv; | ||
| 97 | struct perf_session *session; | ||
| 98 | char *ptr, *pos; | ||
| 99 | size_t size; | ||
| 100 | FILE *fp = open_memstream(&ptr, &size); | ||
| 101 | |||
| 102 | session = container_of(env, struct perf_session, header.env); | ||
| 103 | perf_header__fprintf_info(session, fp, true); | ||
| 104 | fclose(fp); | ||
| 105 | |||
| 106 | for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++) | ||
| 107 | argc++; | ||
| 108 | |||
| 109 | argv = calloc(argc + 1, sizeof(*argv)); | ||
| 110 | if (argv == NULL) | ||
| 111 | goto out; | ||
| 112 | |||
| 113 | argv[0] = pos = ptr; | ||
| 114 | for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) { | ||
| 115 | *pos++ = '\0'; | ||
| 116 | argv[i] = pos; | ||
| 117 | } | ||
| 118 | |||
| 119 | BUG_ON(i != argc + 1); | ||
| 120 | |||
| 121 | ui__list_menu(argc, argv); | ||
| 122 | |||
| 123 | out: | ||
| 124 | free(argv); | ||
| 125 | free(ptr); | ||
| 126 | return 0; | ||
| 127 | } | ||
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a440e03cd8c2..a7045ea6d1d5 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
| @@ -1267,10 +1267,8 @@ static inline void free_popup_options(char **options, int n) | |||
| 1267 | { | 1267 | { |
| 1268 | int i; | 1268 | int i; |
| 1269 | 1269 | ||
| 1270 | for (i = 0; i < n; ++i) { | 1270 | for (i = 0; i < n; ++i) |
| 1271 | free(options[i]); | 1271 | zfree(&options[i]); |
| 1272 | options[i] = NULL; | ||
| 1273 | } | ||
| 1274 | } | 1272 | } |
| 1275 | 1273 | ||
| 1276 | /* Check whether the browser is for 'top' or 'report' */ | 1274 | /* Check whether the browser is for 'top' or 'report' */ |
| @@ -1329,7 +1327,7 @@ static int switch_data_file(void) | |||
| 1329 | 1327 | ||
| 1330 | abs_path[nr_options] = strdup(path); | 1328 | abs_path[nr_options] = strdup(path); |
| 1331 | if (!abs_path[nr_options]) { | 1329 | if (!abs_path[nr_options]) { |
| 1332 | free(options[nr_options]); | 1330 | zfree(&options[nr_options]); |
| 1333 | ui__warning("Can't search all data files due to memory shortage.\n"); | 1331 | ui__warning("Can't search all data files due to memory shortage.\n"); |
| 1334 | fclose(file); | 1332 | fclose(file); |
| 1335 | break; | 1333 | break; |
| @@ -1400,6 +1398,36 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 1400 | char script_opt[64]; | 1398 | char script_opt[64]; |
| 1401 | int delay_secs = hbt ? hbt->refresh : 0; | 1399 | int delay_secs = hbt ? hbt->refresh : 0; |
| 1402 | 1400 | ||
| 1401 | #define HIST_BROWSER_HELP_COMMON \ | ||
| 1402 | "h/?/F1 Show this window\n" \ | ||
| 1403 | "UP/DOWN/PGUP\n" \ | ||
| 1404 | "PGDN/SPACE Navigate\n" \ | ||
| 1405 | "q/ESC/CTRL+C Exit browser\n\n" \ | ||
| 1406 | "For multiple event sessions:\n\n" \ | ||
| 1407 | "TAB/UNTAB Switch events\n\n" \ | ||
| 1408 | "For symbolic views (--sort has sym):\n\n" \ | ||
| 1409 | "-> Zoom into DSO/Threads & Annotate current symbol\n" \ | ||
| 1410 | "<- Zoom out\n" \ | ||
| 1411 | "a Annotate current symbol\n" \ | ||
| 1412 | "C Collapse all callchains\n" \ | ||
| 1413 | "d Zoom into current DSO\n" \ | ||
| 1414 | "E Expand all callchains\n" \ | ||
| 1415 | |||
| 1416 | /* help messages are sorted by lexical order of the hotkey */ | ||
| 1417 | const char report_help[] = HIST_BROWSER_HELP_COMMON | ||
| 1418 | "i Show header information\n" | ||
| 1419 | "P Print histograms to perf.hist.N\n" | ||
| 1420 | "r Run available scripts\n" | ||
| 1421 | "s Switch to another data file in PWD\n" | ||
| 1422 | "t Zoom into current Thread\n" | ||
| 1423 | "V Verbose (DSO names in callchains, etc)\n" | ||
| 1424 | "/ Filter symbol by name"; | ||
| 1425 | const char top_help[] = HIST_BROWSER_HELP_COMMON | ||
| 1426 | "P Print histograms to perf.hist.N\n" | ||
| 1427 | "t Zoom into current Thread\n" | ||
| 1428 | "V Verbose (DSO names in callchains, etc)\n" | ||
| 1429 | "/ Filter symbol by name"; | ||
| 1430 | |||
| 1403 | if (browser == NULL) | 1431 | if (browser == NULL) |
| 1404 | return -1; | 1432 | return -1; |
| 1405 | 1433 | ||
| @@ -1484,29 +1512,16 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 1484 | if (is_report_browser(hbt)) | 1512 | if (is_report_browser(hbt)) |
| 1485 | goto do_data_switch; | 1513 | goto do_data_switch; |
| 1486 | continue; | 1514 | continue; |
| 1515 | case 'i': | ||
| 1516 | /* env->arch is NULL for live-mode (i.e. perf top) */ | ||
| 1517 | if (env->arch) | ||
| 1518 | tui__header_window(env); | ||
| 1519 | continue; | ||
| 1487 | case K_F1: | 1520 | case K_F1: |
| 1488 | case 'h': | 1521 | case 'h': |
| 1489 | case '?': | 1522 | case '?': |
| 1490 | ui_browser__help_window(&browser->b, | 1523 | ui_browser__help_window(&browser->b, |
| 1491 | "h/?/F1 Show this window\n" | 1524 | is_report_browser(hbt) ? report_help : top_help); |
| 1492 | "UP/DOWN/PGUP\n" | ||
| 1493 | "PGDN/SPACE Navigate\n" | ||
| 1494 | "q/ESC/CTRL+C Exit browser\n\n" | ||
| 1495 | "For multiple event sessions:\n\n" | ||
| 1496 | "TAB/UNTAB Switch events\n\n" | ||
| 1497 | "For symbolic views (--sort has sym):\n\n" | ||
| 1498 | "-> Zoom into DSO/Threads & Annotate current symbol\n" | ||
| 1499 | "<- Zoom out\n" | ||
| 1500 | "a Annotate current symbol\n" | ||
| 1501 | "C Collapse all callchains\n" | ||
| 1502 | "E Expand all callchains\n" | ||
| 1503 | "d Zoom into current DSO\n" | ||
| 1504 | "t Zoom into current Thread\n" | ||
| 1505 | "r Run available scripts('perf report' only)\n" | ||
| 1506 | "s Switch to another data file in PWD ('perf report' only)\n" | ||
| 1507 | "P Print histograms to perf.hist.N\n" | ||
| 1508 | "V Verbose (DSO names in callchains, etc)\n" | ||
| 1509 | "/ Filter symbol by name"); | ||
| 1510 | continue; | 1525 | continue; |
| 1511 | case K_ENTER: | 1526 | case K_ENTER: |
| 1512 | case K_RIGHT: | 1527 | case K_RIGHT: |
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index d63c68ea02a8..402d2bd30b09 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c | |||
| @@ -173,8 +173,7 @@ int script_browse(const char *script_opt) | |||
| 173 | if (script.b.width > AVERAGE_LINE_LEN) | 173 | if (script.b.width > AVERAGE_LINE_LEN) |
| 174 | script.b.width = AVERAGE_LINE_LEN; | 174 | script.b.width = AVERAGE_LINE_LEN; |
| 175 | 175 | ||
| 176 | if (line) | 176 | free(line); |
| 177 | free(line); | ||
| 178 | pclose(fp); | 177 | pclose(fp); |
| 179 | 178 | ||
| 180 | script.nr_lines = nr_entries; | 179 | script.nr_lines = nr_entries; |
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index 696c1fbe4248..52e7fc48af9f 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c | |||
| @@ -23,8 +23,7 @@ int perf_gtk__deactivate_context(struct perf_gtk_context **ctx) | |||
| 23 | if (!perf_gtk__is_active_context(*ctx)) | 23 | if (!perf_gtk__is_active_context(*ctx)) |
| 24 | return -1; | 24 | return -1; |
| 25 | 25 | ||
| 26 | free(*ctx); | 26 | zfree(ctx); |
| 27 | *ctx = NULL; | ||
| 28 | return 0; | 27 | return 0; |
| 29 | } | 28 | } |
| 30 | 29 | ||
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index c244cb524ef2..831fbb77d1ff 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
| @@ -510,7 +510,7 @@ print_entries: | |||
| 510 | 510 | ||
| 511 | free(line); | 511 | free(line); |
| 512 | out: | 512 | out: |
| 513 | free(rem_sq_bracket); | 513 | zfree(&rem_sq_bracket); |
| 514 | 514 | ||
| 515 | return ret; | 515 | return ret; |
| 516 | } | 516 | } |
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index 092902e30cee..bf890f72fe80 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c | |||
| @@ -92,6 +92,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input, | |||
| 92 | t = sep + 1; | 92 | t = sep + 1; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | pthread_mutex_lock(&ui__lock); | ||
| 96 | |||
| 95 | max_len += 2; | 97 | max_len += 2; |
| 96 | nr_lines += 8; | 98 | nr_lines += 8; |
| 97 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; | 99 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; |
| @@ -120,13 +122,19 @@ int ui_browser__input_window(const char *title, const char *text, char *input, | |||
| 120 | SLsmg_write_nstring((char *)exit_msg, max_len); | 122 | SLsmg_write_nstring((char *)exit_msg, max_len); |
| 121 | SLsmg_refresh(); | 123 | SLsmg_refresh(); |
| 122 | 124 | ||
| 125 | pthread_mutex_unlock(&ui__lock); | ||
| 126 | |||
| 123 | x += 2; | 127 | x += 2; |
| 124 | len = 0; | 128 | len = 0; |
| 125 | key = ui__getch(delay_secs); | 129 | key = ui__getch(delay_secs); |
| 126 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { | 130 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { |
| 131 | pthread_mutex_lock(&ui__lock); | ||
| 132 | |||
| 127 | if (key == K_BKSPC) { | 133 | if (key == K_BKSPC) { |
| 128 | if (len == 0) | 134 | if (len == 0) { |
| 135 | pthread_mutex_unlock(&ui__lock); | ||
| 129 | goto next_key; | 136 | goto next_key; |
| 137 | } | ||
| 130 | SLsmg_gotorc(y, x + --len); | 138 | SLsmg_gotorc(y, x + --len); |
| 131 | SLsmg_write_char(' '); | 139 | SLsmg_write_char(' '); |
| 132 | } else { | 140 | } else { |
| @@ -136,6 +144,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input, | |||
| 136 | } | 144 | } |
| 137 | SLsmg_refresh(); | 145 | SLsmg_refresh(); |
| 138 | 146 | ||
| 147 | pthread_mutex_unlock(&ui__lock); | ||
| 148 | |||
| 139 | /* XXX more graceful overflow handling needed */ | 149 | /* XXX more graceful overflow handling needed */ |
| 140 | if (len == sizeof(buf) - 1) { | 150 | if (len == sizeof(buf) - 1) { |
| 141 | ui_helpline__push("maximum size of symbol name reached!"); | 151 | ui_helpline__push("maximum size of symbol name reached!"); |
| @@ -174,6 +184,8 @@ int ui__question_window(const char *title, const char *text, | |||
| 174 | t = sep + 1; | 184 | t = sep + 1; |
| 175 | } | 185 | } |
| 176 | 186 | ||
| 187 | pthread_mutex_lock(&ui__lock); | ||
| 188 | |||
| 177 | max_len += 2; | 189 | max_len += 2; |
| 178 | nr_lines += 4; | 190 | nr_lines += 4; |
| 179 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, | 191 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, |
| @@ -195,6 +207,9 @@ int ui__question_window(const char *title, const char *text, | |||
| 195 | SLsmg_gotorc(y + nr_lines - 1, x); | 207 | SLsmg_gotorc(y + nr_lines - 1, x); |
| 196 | SLsmg_write_nstring((char *)exit_msg, max_len); | 208 | SLsmg_write_nstring((char *)exit_msg, max_len); |
| 197 | SLsmg_refresh(); | 209 | SLsmg_refresh(); |
| 210 | |||
| 211 | pthread_mutex_unlock(&ui__lock); | ||
| 212 | |||
| 198 | return ui__getch(delay_secs); | 213 | return ui__getch(delay_secs); |
| 199 | } | 214 | } |
| 200 | 215 | ||
| @@ -215,9 +230,7 @@ static int __ui__warning(const char *title, const char *format, va_list args) | |||
| 215 | if (vasprintf(&s, format, args) > 0) { | 230 | if (vasprintf(&s, format, args) > 0) { |
| 216 | int key; | 231 | int key; |
| 217 | 232 | ||
| 218 | pthread_mutex_lock(&ui__lock); | ||
| 219 | key = ui__question_window(title, s, "Press any key...", 0); | 233 | key = ui__question_window(title, s, "Press any key...", 0); |
| 220 | pthread_mutex_unlock(&ui__lock); | ||
| 221 | free(s); | 234 | free(s); |
| 222 | return key; | 235 | return key; |
| 223 | } | 236 | } |
diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c index e6d134773d0a..c0b43ee40d95 100644 --- a/tools/perf/util/alias.c +++ b/tools/perf/util/alias.c | |||
| @@ -55,8 +55,7 @@ int split_cmdline(char *cmdline, const char ***argv) | |||
| 55 | src++; | 55 | src++; |
| 56 | c = cmdline[src]; | 56 | c = cmdline[src]; |
| 57 | if (!c) { | 57 | if (!c) { |
| 58 | free(*argv); | 58 | zfree(argv); |
| 59 | *argv = NULL; | ||
| 60 | return error("cmdline ends with \\"); | 59 | return error("cmdline ends with \\"); |
| 61 | } | 60 | } |
| 62 | } | 61 | } |
| @@ -68,8 +67,7 @@ int split_cmdline(char *cmdline, const char ***argv) | |||
| 68 | cmdline[dst] = 0; | 67 | cmdline[dst] = 0; |
| 69 | 68 | ||
| 70 | if (quoted) { | 69 | if (quoted) { |
| 71 | free(*argv); | 70 | zfree(argv); |
| 72 | *argv = NULL; | ||
| 73 | return error("unclosed quote"); | 71 | return error("unclosed quote"); |
| 74 | } | 72 | } |
| 75 | 73 | ||
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 0fcd81ea31ae..469eb679fb9d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -26,10 +26,10 @@ static int disasm_line__parse(char *line, char **namep, char **rawp); | |||
| 26 | 26 | ||
| 27 | static void ins__delete(struct ins_operands *ops) | 27 | static void ins__delete(struct ins_operands *ops) |
| 28 | { | 28 | { |
| 29 | free(ops->source.raw); | 29 | zfree(&ops->source.raw); |
| 30 | free(ops->source.name); | 30 | zfree(&ops->source.name); |
| 31 | free(ops->target.raw); | 31 | zfree(&ops->target.raw); |
| 32 | free(ops->target.name); | 32 | zfree(&ops->target.name); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, | 35 | static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, |
| @@ -185,8 +185,7 @@ static int lock__parse(struct ins_operands *ops) | |||
| 185 | return 0; | 185 | return 0; |
| 186 | 186 | ||
| 187 | out_free_ops: | 187 | out_free_ops: |
| 188 | free(ops->locked.ops); | 188 | zfree(&ops->locked.ops); |
| 189 | ops->locked.ops = NULL; | ||
| 190 | return 0; | 189 | return 0; |
| 191 | } | 190 | } |
| 192 | 191 | ||
| @@ -205,9 +204,9 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, | |||
| 205 | 204 | ||
| 206 | static void lock__delete(struct ins_operands *ops) | 205 | static void lock__delete(struct ins_operands *ops) |
| 207 | { | 206 | { |
| 208 | free(ops->locked.ops); | 207 | zfree(&ops->locked.ops); |
| 209 | free(ops->target.raw); | 208 | zfree(&ops->target.raw); |
| 210 | free(ops->target.name); | 209 | zfree(&ops->target.name); |
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | static struct ins_ops lock_ops = { | 212 | static struct ins_ops lock_ops = { |
| @@ -256,8 +255,7 @@ static int mov__parse(struct ins_operands *ops) | |||
| 256 | return 0; | 255 | return 0; |
| 257 | 256 | ||
| 258 | out_free_source: | 257 | out_free_source: |
| 259 | free(ops->source.raw); | 258 | zfree(&ops->source.raw); |
| 260 | ops->source.raw = NULL; | ||
| 261 | return -1; | 259 | return -1; |
| 262 | } | 260 | } |
| 263 | 261 | ||
| @@ -464,17 +462,12 @@ void symbol__annotate_zero_histograms(struct symbol *sym) | |||
| 464 | pthread_mutex_unlock(¬es->lock); | 462 | pthread_mutex_unlock(¬es->lock); |
| 465 | } | 463 | } |
| 466 | 464 | ||
| 467 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 465 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
| 468 | int evidx, u64 addr) | 466 | struct annotation *notes, int evidx, u64 addr) |
| 469 | { | 467 | { |
| 470 | unsigned offset; | 468 | unsigned offset; |
| 471 | struct annotation *notes; | ||
| 472 | struct sym_hist *h; | 469 | struct sym_hist *h; |
| 473 | 470 | ||
| 474 | notes = symbol__annotation(sym); | ||
| 475 | if (notes->src == NULL) | ||
| 476 | return -ENOMEM; | ||
| 477 | |||
| 478 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); | 471 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); |
| 479 | 472 | ||
| 480 | if (addr < sym->start || addr > sym->end) | 473 | if (addr < sym->start || addr > sym->end) |
| @@ -491,6 +484,33 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
| 491 | return 0; | 484 | return 0; |
| 492 | } | 485 | } |
| 493 | 486 | ||
| 487 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | ||
| 488 | int evidx, u64 addr) | ||
| 489 | { | ||
| 490 | struct annotation *notes; | ||
| 491 | |||
| 492 | if (sym == NULL || use_browser != 1 || !sort__has_sym) | ||
| 493 | return 0; | ||
| 494 | |||
| 495 | notes = symbol__annotation(sym); | ||
| 496 | if (notes->src == NULL) { | ||
| 497 | if (symbol__alloc_hist(sym) < 0) | ||
| 498 | return -ENOMEM; | ||
| 499 | } | ||
| 500 | |||
| 501 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); | ||
| 502 | } | ||
| 503 | |||
| 504 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) | ||
| 505 | { | ||
| 506 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); | ||
| 507 | } | ||
| 508 | |||
| 509 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | ||
| 510 | { | ||
| 511 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | ||
| 512 | } | ||
| 513 | |||
| 494 | static void disasm_line__init_ins(struct disasm_line *dl) | 514 | static void disasm_line__init_ins(struct disasm_line *dl) |
| 495 | { | 515 | { |
| 496 | dl->ins = ins__find(dl->name); | 516 | dl->ins = ins__find(dl->name); |
| @@ -538,8 +558,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp) | |||
| 538 | return 0; | 558 | return 0; |
| 539 | 559 | ||
| 540 | out_free_name: | 560 | out_free_name: |
| 541 | free(*namep); | 561 | zfree(namep); |
| 542 | *namep = NULL; | ||
| 543 | return -1; | 562 | return -1; |
| 544 | } | 563 | } |
| 545 | 564 | ||
| @@ -564,7 +583,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs | |||
| 564 | return dl; | 583 | return dl; |
| 565 | 584 | ||
| 566 | out_free_line: | 585 | out_free_line: |
| 567 | free(dl->line); | 586 | zfree(&dl->line); |
| 568 | out_delete: | 587 | out_delete: |
| 569 | free(dl); | 588 | free(dl); |
| 570 | return NULL; | 589 | return NULL; |
| @@ -572,8 +591,8 @@ out_delete: | |||
| 572 | 591 | ||
| 573 | void disasm_line__free(struct disasm_line *dl) | 592 | void disasm_line__free(struct disasm_line *dl) |
| 574 | { | 593 | { |
| 575 | free(dl->line); | 594 | zfree(&dl->line); |
| 576 | free(dl->name); | 595 | zfree(&dl->name); |
| 577 | if (dl->ins && dl->ins->ops->free) | 596 | if (dl->ins && dl->ins->ops->free) |
| 578 | dl->ins->ops->free(&dl->ops); | 597 | dl->ins->ops->free(&dl->ops); |
| 579 | else | 598 | else |
| @@ -1091,8 +1110,7 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
| 1091 | src_line = (void *)src_line + sizeof_src_line; | 1110 | src_line = (void *)src_line + sizeof_src_line; |
| 1092 | } | 1111 | } |
| 1093 | 1112 | ||
| 1094 | free(notes->src->lines); | 1113 | zfree(¬es->src->lines); |
| 1095 | notes->src->lines = NULL; | ||
| 1096 | } | 1114 | } |
| 1097 | 1115 | ||
| 1098 | /* Get the filename:line for the colored entries */ | 1116 | /* Get the filename:line for the colored entries */ |
| @@ -1376,3 +1394,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
| 1376 | 1394 | ||
| 1377 | return 0; | 1395 | return 0; |
| 1378 | } | 1396 | } |
| 1397 | |||
| 1398 | int hist_entry__annotate(struct hist_entry *he, size_t privsize) | ||
| 1399 | { | ||
| 1400 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | ||
| 1401 | } | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 834b7b57b788..b2aef59d6bb2 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
| @@ -132,12 +132,17 @@ static inline struct annotation *symbol__annotation(struct symbol *sym) | |||
| 132 | return &a->annotation; | 132 | return &a->annotation; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 135 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); |
| 136 | int evidx, u64 addr); | 136 | |
| 137 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); | ||
| 138 | |||
| 137 | int symbol__alloc_hist(struct symbol *sym); | 139 | int symbol__alloc_hist(struct symbol *sym); |
| 138 | void symbol__annotate_zero_histograms(struct symbol *sym); | 140 | void symbol__annotate_zero_histograms(struct symbol *sym); |
| 139 | 141 | ||
| 140 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); | 142 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); |
| 143 | |||
| 144 | int hist_entry__annotate(struct hist_entry *he, size_t privsize); | ||
| 145 | |||
| 141 | int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); | 146 | int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); |
| 142 | int symbol__annotate_printf(struct symbol *sym, struct map *map, | 147 | int symbol__annotate_printf(struct symbol *sym, struct map *map, |
| 143 | struct perf_evsel *evsel, bool full_paths, | 148 | struct perf_evsel *evsel, bool full_paths, |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 4f7f989876ec..08b25af9eea1 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
| @@ -146,7 +146,7 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor) | |||
| 146 | 146 | ||
| 147 | struct option; | 147 | struct option; |
| 148 | 148 | ||
| 149 | int record_parse_callchain(const char *arg, struct perf_record_opts *opts); | 149 | int record_parse_callchain(const char *arg, struct record_opts *opts); |
| 150 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); | 150 | int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); |
| 151 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); | 151 | int record_callchain_opt(const struct option *opt, const char *arg, int unset); |
| 152 | 152 | ||
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 96bbda1ddb83..0922aa4218c2 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c | |||
| @@ -133,7 +133,7 @@ void close_cgroup(struct cgroup_sel *cgrp) | |||
| 133 | /* XXX: not reentrant */ | 133 | /* XXX: not reentrant */ |
| 134 | if (--cgrp->refcnt == 0) { | 134 | if (--cgrp->refcnt == 0) { |
| 135 | close(cgrp->fd); | 135 | close(cgrp->fd); |
| 136 | free(cgrp->name); | 136 | zfree(&cgrp->name); |
| 137 | free(cgrp); | 137 | free(cgrp); |
| 138 | } | 138 | } |
| 139 | } | 139 | } |
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index ee0df0e24cdb..67d1e404c0cb 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
| @@ -21,7 +21,7 @@ static void comm_str__put(struct comm_str *cs) | |||
| 21 | { | 21 | { |
| 22 | if (!--cs->ref) { | 22 | if (!--cs->ref) { |
| 23 | rb_erase(&cs->rb_node, &comm_str_root); | 23 | rb_erase(&cs->rb_node, &comm_str_root); |
| 24 | free(cs->str); | 24 | zfree(&cs->str); |
| 25 | free(cs); | 25 | free(cs); |
| 26 | } | 26 | } |
| 27 | } | 27 | } |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 8640a9121e72..299b55586502 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
| @@ -25,7 +25,6 @@ static int _eprintf(int level, const char *fmt, va_list args) | |||
| 25 | ui_helpline__vshow(fmt, args); | 25 | ui_helpline__vshow(fmt, args); |
| 26 | else | 26 | else |
| 27 | ret = vfprintf(stderr, fmt, args); | 27 | ret = vfprintf(stderr, fmt, args); |
| 28 | va_end(args); | ||
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | return ret; | 30 | return ret; |
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 4ddeecb9ff85..4045d086d9d9 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
| @@ -497,21 +497,18 @@ void dso__delete(struct dso *dso) | |||
| 497 | symbols__delete(&dso->symbols[i]); | 497 | symbols__delete(&dso->symbols[i]); |
| 498 | 498 | ||
| 499 | if (dso->short_name_allocated) { | 499 | if (dso->short_name_allocated) { |
| 500 | free((char *)dso->short_name); | 500 | zfree((char **)&dso->short_name); |
| 501 | dso->short_name = NULL; | ||
| 502 | dso->short_name_allocated = false; | 501 | dso->short_name_allocated = false; |
| 503 | } | 502 | } |
| 504 | 503 | ||
| 505 | if (dso->long_name_allocated) { | 504 | if (dso->long_name_allocated) { |
| 506 | free((char *)dso->long_name); | 505 | zfree((char **)&dso->long_name); |
| 507 | dso->long_name = NULL; | ||
| 508 | dso->long_name_allocated = false; | 506 | dso->long_name_allocated = false; |
| 509 | } | 507 | } |
| 510 | 508 | ||
| 511 | dso_cache__free(&dso->cache); | 509 | dso_cache__free(&dso->cache); |
| 512 | dso__free_a2l(dso); | 510 | dso__free_a2l(dso); |
| 513 | free(dso->symsrc_filename); | 511 | zfree(&dso->symsrc_filename); |
| 514 | dso->symsrc_filename = NULL; | ||
| 515 | free(dso); | 512 | free(dso); |
| 516 | } | 513 | } |
| 517 | 514 | ||
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 694876877ae2..45a76c69a9ed 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -106,8 +106,12 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, | |||
| 106 | 106 | ||
| 107 | memset(&event->comm, 0, sizeof(event->comm)); | 107 | memset(&event->comm, 0, sizeof(event->comm)); |
| 108 | 108 | ||
| 109 | tgid = perf_event__get_comm_tgid(pid, event->comm.comm, | 109 | if (machine__is_host(machine)) |
| 110 | sizeof(event->comm.comm)); | 110 | tgid = perf_event__get_comm_tgid(pid, event->comm.comm, |
| 111 | sizeof(event->comm.comm)); | ||
| 112 | else | ||
| 113 | tgid = machine->pid; | ||
| 114 | |||
| 111 | if (tgid < 0) | 115 | if (tgid < 0) |
| 112 | goto out; | 116 | goto out; |
| 113 | 117 | ||
| @@ -129,7 +133,11 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, | |||
| 129 | goto out; | 133 | goto out; |
| 130 | } | 134 | } |
| 131 | 135 | ||
| 132 | snprintf(filename, sizeof(filename), "/proc/%d/task", pid); | 136 | if (machine__is_default_guest(machine)) |
| 137 | return 0; | ||
| 138 | |||
| 139 | snprintf(filename, sizeof(filename), "%s/proc/%d/task", | ||
| 140 | machine->root_dir, pid); | ||
| 133 | 141 | ||
| 134 | tasks = opendir(filename); | 142 | tasks = opendir(filename); |
| 135 | if (tasks == NULL) { | 143 | if (tasks == NULL) { |
| @@ -178,7 +186,11 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
| 178 | FILE *fp; | 186 | FILE *fp; |
| 179 | int rc = 0; | 187 | int rc = 0; |
| 180 | 188 | ||
| 181 | snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); | 189 | if (machine__is_default_guest(machine)) |
| 190 | return 0; | ||
| 191 | |||
| 192 | snprintf(filename, sizeof(filename), "%s/proc/%d/maps", | ||
| 193 | machine->root_dir, pid); | ||
| 182 | 194 | ||
| 183 | fp = fopen(filename, "r"); | 195 | fp = fopen(filename, "r"); |
| 184 | if (fp == NULL) { | 196 | if (fp == NULL) { |
| @@ -218,7 +230,10 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
| 218 | /* | 230 | /* |
| 219 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | 231 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c |
| 220 | */ | 232 | */ |
| 221 | event->header.misc = PERF_RECORD_MISC_USER; | 233 | if (machine__is_host(machine)) |
| 234 | event->header.misc = PERF_RECORD_MISC_USER; | ||
| 235 | else | ||
| 236 | event->header.misc = PERF_RECORD_MISC_GUEST_USER; | ||
| 222 | 237 | ||
| 223 | if (prot[2] != 'x') { | 238 | if (prot[2] != 'x') { |
| 224 | if (!mmap_data || prot[0] != 'r') | 239 | if (!mmap_data || prot[0] != 'r') |
| @@ -387,6 +402,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
| 387 | struct machine *machine, bool mmap_data) | 402 | struct machine *machine, bool mmap_data) |
| 388 | { | 403 | { |
| 389 | DIR *proc; | 404 | DIR *proc; |
| 405 | char proc_path[PATH_MAX]; | ||
| 390 | struct dirent dirent, *next; | 406 | struct dirent dirent, *next; |
| 391 | union perf_event *comm_event, *mmap_event; | 407 | union perf_event *comm_event, *mmap_event; |
| 392 | int err = -1; | 408 | int err = -1; |
| @@ -399,7 +415,12 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
| 399 | if (mmap_event == NULL) | 415 | if (mmap_event == NULL) |
| 400 | goto out_free_comm; | 416 | goto out_free_comm; |
| 401 | 417 | ||
| 402 | proc = opendir("/proc"); | 418 | if (machine__is_default_guest(machine)) |
| 419 | return 0; | ||
| 420 | |||
| 421 | snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); | ||
| 422 | proc = opendir(proc_path); | ||
| 423 | |||
| 403 | if (proc == NULL) | 424 | if (proc == NULL) |
| 404 | goto out_free_mmap; | 425 | goto out_free_mmap; |
| 405 | 426 | ||
| @@ -638,6 +659,7 @@ void thread__find_addr_map(struct thread *thread, | |||
| 638 | struct map_groups *mg = &thread->mg; | 659 | struct map_groups *mg = &thread->mg; |
| 639 | bool load_map = false; | 660 | bool load_map = false; |
| 640 | 661 | ||
| 662 | al->machine = machine; | ||
| 641 | al->thread = thread; | 663 | al->thread = thread; |
| 642 | al->addr = addr; | 664 | al->addr = addr; |
| 643 | al->cpumode = cpumode; | 665 | al->cpumode = cpumode; |
| @@ -658,15 +680,10 @@ void thread__find_addr_map(struct thread *thread, | |||
| 658 | al->level = 'g'; | 680 | al->level = 'g'; |
| 659 | mg = &machine->kmaps; | 681 | mg = &machine->kmaps; |
| 660 | load_map = true; | 682 | load_map = true; |
| 683 | } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { | ||
| 684 | al->level = 'u'; | ||
| 661 | } else { | 685 | } else { |
| 662 | /* | 686 | al->level = 'H'; |
| 663 | * 'u' means guest os user space. | ||
| 664 | * TODO: We don't support guest user space. Might support late. | ||
| 665 | */ | ||
| 666 | if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) | ||
| 667 | al->level = 'u'; | ||
| 668 | else | ||
| 669 | al->level = 'H'; | ||
| 670 | al->map = NULL; | 687 | al->map = NULL; |
| 671 | 688 | ||
| 672 | if ((cpumode == PERF_RECORD_MISC_GUEST_USER || | 689 | if ((cpumode == PERF_RECORD_MISC_GUEST_USER || |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index da3182914984..b08a7ecdcea1 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -101,10 +101,8 @@ static void perf_evlist__purge(struct perf_evlist *evlist) | |||
| 101 | 101 | ||
| 102 | void perf_evlist__exit(struct perf_evlist *evlist) | 102 | void perf_evlist__exit(struct perf_evlist *evlist) |
| 103 | { | 103 | { |
| 104 | free(evlist->mmap); | 104 | zfree(&evlist->mmap); |
| 105 | free(evlist->pollfd); | 105 | zfree(&evlist->pollfd); |
| 106 | evlist->mmap = NULL; | ||
| 107 | evlist->pollfd = NULL; | ||
| 108 | } | 106 | } |
| 109 | 107 | ||
| 110 | void perf_evlist__delete(struct perf_evlist *evlist) | 108 | void perf_evlist__delete(struct perf_evlist *evlist) |
| @@ -587,8 +585,7 @@ void perf_evlist__munmap(struct perf_evlist *evlist) | |||
| 587 | for (i = 0; i < evlist->nr_mmaps; i++) | 585 | for (i = 0; i < evlist->nr_mmaps; i++) |
| 588 | __perf_evlist__munmap(evlist, i); | 586 | __perf_evlist__munmap(evlist, i); |
| 589 | 587 | ||
| 590 | free(evlist->mmap); | 588 | zfree(&evlist->mmap); |
| 591 | evlist->mmap = NULL; | ||
| 592 | } | 589 | } |
| 593 | 590 | ||
| 594 | static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) | 591 | static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 9f64ede3ecbd..2fe51958ed85 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | struct pollfd; | 12 | struct pollfd; |
| 13 | struct thread_map; | 13 | struct thread_map; |
| 14 | struct cpu_map; | 14 | struct cpu_map; |
| 15 | struct perf_record_opts; | 15 | struct record_opts; |
| 16 | 16 | ||
| 17 | #define PERF_EVLIST__HLIST_BITS 8 | 17 | #define PERF_EVLIST__HLIST_BITS 8 |
| 18 | #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) | 18 | #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) |
| @@ -97,9 +97,8 @@ void perf_evlist__close(struct perf_evlist *evlist); | |||
| 97 | 97 | ||
| 98 | void perf_evlist__set_id_pos(struct perf_evlist *evlist); | 98 | void perf_evlist__set_id_pos(struct perf_evlist *evlist); |
| 99 | bool perf_can_sample_identifier(void); | 99 | bool perf_can_sample_identifier(void); |
| 100 | void perf_evlist__config(struct perf_evlist *evlist, | 100 | void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts); |
| 101 | struct perf_record_opts *opts); | 101 | int record_opts__config(struct record_opts *opts); |
| 102 | int perf_record_opts__config(struct perf_record_opts *opts); | ||
| 103 | 102 | ||
| 104 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, | 103 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, |
| 105 | struct target *target, | 104 | struct target *target, |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 01ff4cfde1f5..ade8d9c1c431 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -208,7 +208,7 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int | |||
| 208 | return evsel; | 208 | return evsel; |
| 209 | 209 | ||
| 210 | out_free: | 210 | out_free: |
| 211 | free(evsel->name); | 211 | zfree(&evsel->name); |
| 212 | free(evsel); | 212 | free(evsel); |
| 213 | return NULL; | 213 | return NULL; |
| 214 | } | 214 | } |
| @@ -528,8 +528,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) | |||
| 528 | * enable/disable events specifically, as there's no | 528 | * enable/disable events specifically, as there's no |
| 529 | * initial traced exec call. | 529 | * initial traced exec call. |
| 530 | */ | 530 | */ |
| 531 | void perf_evsel__config(struct perf_evsel *evsel, | 531 | void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) |
| 532 | struct perf_record_opts *opts) | ||
| 533 | { | 532 | { |
| 534 | struct perf_evsel *leader = evsel->leader; | 533 | struct perf_evsel *leader = evsel->leader; |
| 535 | struct perf_event_attr *attr = &evsel->attr; | 534 | struct perf_event_attr *attr = &evsel->attr; |
| @@ -751,8 +750,7 @@ void perf_evsel__free_id(struct perf_evsel *evsel) | |||
| 751 | { | 750 | { |
| 752 | xyarray__delete(evsel->sample_id); | 751 | xyarray__delete(evsel->sample_id); |
| 753 | evsel->sample_id = NULL; | 752 | evsel->sample_id = NULL; |
| 754 | free(evsel->id); | 753 | zfree(&evsel->id); |
| 755 | evsel->id = NULL; | ||
| 756 | } | 754 | } |
| 757 | 755 | ||
| 758 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 756 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
| @@ -768,7 +766,7 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | |||
| 768 | 766 | ||
| 769 | void perf_evsel__free_counts(struct perf_evsel *evsel) | 767 | void perf_evsel__free_counts(struct perf_evsel *evsel) |
| 770 | { | 768 | { |
| 771 | free(evsel->counts); | 769 | zfree(&evsel->counts); |
| 772 | } | 770 | } |
| 773 | 771 | ||
| 774 | void perf_evsel__exit(struct perf_evsel *evsel) | 772 | void perf_evsel__exit(struct perf_evsel *evsel) |
| @@ -782,10 +780,10 @@ void perf_evsel__delete(struct perf_evsel *evsel) | |||
| 782 | { | 780 | { |
| 783 | perf_evsel__exit(evsel); | 781 | perf_evsel__exit(evsel); |
| 784 | close_cgroup(evsel->cgrp); | 782 | close_cgroup(evsel->cgrp); |
| 785 | free(evsel->group_name); | 783 | zfree(&evsel->group_name); |
| 786 | if (evsel->tp_format) | 784 | if (evsel->tp_format) |
| 787 | pevent_free_format(evsel->tp_format); | 785 | pevent_free_format(evsel->tp_format); |
| 788 | free(evsel->name); | 786 | zfree(&evsel->name); |
| 789 | free(evsel); | 787 | free(evsel); |
| 790 | } | 788 | } |
| 791 | 789 | ||
| @@ -1961,8 +1959,7 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | |||
| 1961 | evsel->attr.type = PERF_TYPE_SOFTWARE; | 1959 | evsel->attr.type = PERF_TYPE_SOFTWARE; |
| 1962 | evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; | 1960 | evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; |
| 1963 | 1961 | ||
| 1964 | free(evsel->name); | 1962 | zfree(&evsel->name); |
| 1965 | evsel->name = NULL; | ||
| 1966 | return true; | 1963 | return true; |
| 1967 | } | 1964 | } |
| 1968 | 1965 | ||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 8120eeb86ac1..f1b325665aae 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -96,7 +96,7 @@ struct perf_evsel { | |||
| 96 | struct cpu_map; | 96 | struct cpu_map; |
| 97 | struct thread_map; | 97 | struct thread_map; |
| 98 | struct perf_evlist; | 98 | struct perf_evlist; |
| 99 | struct perf_record_opts; | 99 | struct record_opts; |
| 100 | 100 | ||
| 101 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); | 101 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); |
| 102 | 102 | ||
| @@ -120,7 +120,7 @@ void perf_evsel__exit(struct perf_evsel *evsel); | |||
| 120 | void perf_evsel__delete(struct perf_evsel *evsel); | 120 | void perf_evsel__delete(struct perf_evsel *evsel); |
| 121 | 121 | ||
| 122 | void perf_evsel__config(struct perf_evsel *evsel, | 122 | void perf_evsel__config(struct perf_evsel *evsel, |
| 123 | struct perf_record_opts *opts); | 123 | struct record_opts *opts); |
| 124 | 124 | ||
| 125 | int __perf_evsel__sample_size(u64 sample_type); | 125 | int __perf_evsel__sample_size(u64 sample_type); |
| 126 | void perf_evsel__calc_id_pos(struct perf_evsel *evsel); | 126 | void perf_evsel__calc_id_pos(struct perf_evsel *evsel); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 61c54213704b..a4a60b7887ee 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -800,10 +800,10 @@ static void free_cpu_topo(struct cpu_topo *tp) | |||
| 800 | return; | 800 | return; |
| 801 | 801 | ||
| 802 | for (i = 0 ; i < tp->core_sib; i++) | 802 | for (i = 0 ; i < tp->core_sib; i++) |
| 803 | free(tp->core_siblings[i]); | 803 | zfree(&tp->core_siblings[i]); |
| 804 | 804 | ||
| 805 | for (i = 0 ; i < tp->thread_sib; i++) | 805 | for (i = 0 ; i < tp->thread_sib; i++) |
| 806 | free(tp->thread_siblings[i]); | 806 | zfree(&tp->thread_siblings[i]); |
| 807 | 807 | ||
| 808 | free(tp); | 808 | free(tp); |
| 809 | } | 809 | } |
| @@ -1232,10 +1232,8 @@ static void free_event_desc(struct perf_evsel *events) | |||
| 1232 | return; | 1232 | return; |
| 1233 | 1233 | ||
| 1234 | for (evsel = events; evsel->attr.size; evsel++) { | 1234 | for (evsel = events; evsel->attr.size; evsel++) { |
| 1235 | if (evsel->name) | 1235 | zfree(&evsel->name); |
| 1236 | free(evsel->name); | 1236 | zfree(&evsel->id); |
| 1237 | if (evsel->id) | ||
| 1238 | free(evsel->id); | ||
| 1239 | } | 1237 | } |
| 1240 | 1238 | ||
| 1241 | free(events); | 1239 | free(events); |
| @@ -1326,8 +1324,7 @@ read_event_desc(struct perf_header *ph, int fd) | |||
| 1326 | } | 1324 | } |
| 1327 | } | 1325 | } |
| 1328 | out: | 1326 | out: |
| 1329 | if (buf) | 1327 | free(buf); |
| 1330 | free(buf); | ||
| 1331 | return events; | 1328 | return events; |
| 1332 | error: | 1329 | error: |
| 1333 | if (events) | 1330 | if (events) |
| @@ -2108,7 +2105,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, | |||
| 2108 | ret = 0; | 2105 | ret = 0; |
| 2109 | out_free: | 2106 | out_free: |
| 2110 | for (i = 0; i < nr_groups; i++) | 2107 | for (i = 0; i < nr_groups; i++) |
| 2111 | free(desc[i].name); | 2108 | zfree(&desc[i].name); |
| 2112 | free(desc); | 2109 | free(desc); |
| 2113 | 2110 | ||
| 2114 | return ret; | 2111 | return ret; |
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 8b1f6e891b8a..86c37c472263 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c | |||
| @@ -22,8 +22,8 @@ static void clean_cmdnames(struct cmdnames *cmds) | |||
| 22 | unsigned int i; | 22 | unsigned int i; |
| 23 | 23 | ||
| 24 | for (i = 0; i < cmds->cnt; ++i) | 24 | for (i = 0; i < cmds->cnt; ++i) |
| 25 | free(cmds->names[i]); | 25 | zfree(&cmds->names[i]); |
| 26 | free(cmds->names); | 26 | zfree(&cmds->names); |
| 27 | cmds->cnt = 0; | 27 | cmds->cnt = 0; |
| 28 | cmds->alloc = 0; | 28 | cmds->alloc = 0; |
| 29 | } | 29 | } |
| @@ -263,9 +263,8 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) | |||
| 263 | 263 | ||
| 264 | for (i = 0; i < old->cnt; i++) | 264 | for (i = 0; i < old->cnt; i++) |
| 265 | cmds->names[cmds->cnt++] = old->names[i]; | 265 | cmds->names[cmds->cnt++] = old->names[i]; |
| 266 | free(old->names); | 266 | zfree(&old->names); |
| 267 | old->cnt = 0; | 267 | old->cnt = 0; |
| 268 | old->names = NULL; | ||
| 269 | } | 268 | } |
| 270 | 269 | ||
| 271 | const char *help_unknown_cmd(const char *cmd) | 270 | const char *help_unknown_cmd(const char *cmd) |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 822903eaa201..4ed3e883240d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | #include "annotate.h" | ||
| 2 | #include "util.h" | 1 | #include "util.h" |
| 3 | #include "build-id.h" | 2 | #include "build-id.h" |
| 4 | #include "hist.h" | 3 | #include "hist.h" |
| @@ -342,15 +341,15 @@ static u8 symbol__parent_filter(const struct symbol *parent) | |||
| 342 | } | 341 | } |
| 343 | 342 | ||
| 344 | static struct hist_entry *add_hist_entry(struct hists *hists, | 343 | static struct hist_entry *add_hist_entry(struct hists *hists, |
| 345 | struct hist_entry *entry, | 344 | struct hist_entry *entry, |
| 346 | struct addr_location *al, | 345 | struct addr_location *al) |
| 347 | u64 period, | ||
| 348 | u64 weight) | ||
| 349 | { | 346 | { |
| 350 | struct rb_node **p; | 347 | struct rb_node **p; |
| 351 | struct rb_node *parent = NULL; | 348 | struct rb_node *parent = NULL; |
| 352 | struct hist_entry *he; | 349 | struct hist_entry *he; |
| 353 | int64_t cmp; | 350 | int64_t cmp; |
| 351 | u64 period = entry->stat.period; | ||
| 352 | u64 weight = entry->stat.weight; | ||
| 354 | 353 | ||
| 355 | p = &hists->entries_in->rb_node; | 354 | p = &hists->entries_in->rb_node; |
| 356 | 355 | ||
| @@ -373,7 +372,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
| 373 | * This mem info was allocated from machine__resolve_mem | 372 | * This mem info was allocated from machine__resolve_mem |
| 374 | * and will not be used anymore. | 373 | * and will not be used anymore. |
| 375 | */ | 374 | */ |
| 376 | free(entry->mem_info); | 375 | zfree(&entry->mem_info); |
| 377 | 376 | ||
| 378 | /* If the map of an existing hist_entry has | 377 | /* If the map of an existing hist_entry has |
| 379 | * become out-of-date due to an exec() or | 378 | * become out-of-date due to an exec() or |
| @@ -437,7 +436,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists, | |||
| 437 | .transaction = transaction, | 436 | .transaction = transaction, |
| 438 | }; | 437 | }; |
| 439 | 438 | ||
| 440 | return add_hist_entry(hists, &entry, al, period, weight); | 439 | return add_hist_entry(hists, &entry, al); |
| 441 | } | 440 | } |
| 442 | 441 | ||
| 443 | int64_t | 442 | int64_t |
| @@ -476,8 +475,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) | |||
| 476 | 475 | ||
| 477 | void hist_entry__free(struct hist_entry *he) | 476 | void hist_entry__free(struct hist_entry *he) |
| 478 | { | 477 | { |
| 479 | free(he->branch_info); | 478 | zfree(&he->branch_info); |
| 480 | free(he->mem_info); | 479 | zfree(&he->mem_info); |
| 481 | free_srcline(he->srcline); | 480 | free_srcline(he->srcline); |
| 482 | free(he); | 481 | free(he); |
| 483 | } | 482 | } |
| @@ -807,16 +806,6 @@ void hists__filter_by_symbol(struct hists *hists) | |||
| 807 | } | 806 | } |
| 808 | } | 807 | } |
| 809 | 808 | ||
| 810 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | ||
| 811 | { | ||
| 812 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | ||
| 813 | } | ||
| 814 | |||
| 815 | int hist_entry__annotate(struct hist_entry *he, size_t privsize) | ||
| 816 | { | ||
| 817 | return symbol__annotate(he->ms.sym, he->ms.map, privsize); | ||
| 818 | } | ||
| 819 | |||
| 820 | void events_stats__inc(struct events_stats *stats, u32 type) | 809 | void events_stats__inc(struct events_stats *stats, u32 type) |
| 821 | { | 810 | { |
| 822 | ++stats->nr_events[0]; | 811 | ++stats->nr_events[0]; |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index b621347a1585..a59743fa3ef7 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -111,9 +111,6 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); | |||
| 111 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | 111 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, |
| 112 | int max_cols, float min_pcnt, FILE *fp); | 112 | int max_cols, float min_pcnt, FILE *fp); |
| 113 | 113 | ||
| 114 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); | ||
| 115 | int hist_entry__annotate(struct hist_entry *he, size_t privsize); | ||
| 116 | |||
| 117 | void hists__filter_by_dso(struct hists *hists); | 114 | void hists__filter_by_dso(struct hists *hists); |
| 118 | void hists__filter_by_thread(struct hists *hists); | 115 | void hists__filter_by_thread(struct hists *hists); |
| 119 | void hists__filter_by_symbol(struct hists *hists); | 116 | void hists__filter_by_symbol(struct hists *hists); |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index c78cc84f433e..a98538dc465a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -102,8 +102,7 @@ void machine__exit(struct machine *machine) | |||
| 102 | map_groups__exit(&machine->kmaps); | 102 | map_groups__exit(&machine->kmaps); |
| 103 | dsos__delete(&machine->user_dsos); | 103 | dsos__delete(&machine->user_dsos); |
| 104 | dsos__delete(&machine->kernel_dsos); | 104 | dsos__delete(&machine->kernel_dsos); |
| 105 | free(machine->root_dir); | 105 | zfree(&machine->root_dir); |
| 106 | machine->root_dir = NULL; | ||
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | void machine__delete(struct machine *machine) | 108 | void machine__delete(struct machine *machine) |
| @@ -562,11 +561,10 @@ void machine__destroy_kernel_maps(struct machine *machine) | |||
| 562 | * on one of them. | 561 | * on one of them. |
| 563 | */ | 562 | */ |
| 564 | if (type == MAP__FUNCTION) { | 563 | if (type == MAP__FUNCTION) { |
| 565 | free((char *)kmap->ref_reloc_sym->name); | 564 | zfree((char **)&kmap->ref_reloc_sym->name); |
| 566 | kmap->ref_reloc_sym->name = NULL; | 565 | zfree(&kmap->ref_reloc_sym); |
| 567 | free(kmap->ref_reloc_sym); | 566 | } else |
| 568 | } | 567 | kmap->ref_reloc_sym = NULL; |
| 569 | kmap->ref_reloc_sym = NULL; | ||
| 570 | } | 568 | } |
| 571 | 569 | ||
| 572 | map__delete(machine->vmlinux_maps[type]); | 570 | map__delete(machine->vmlinux_maps[type]); |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 094c28ba2fae..0153435b8427 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -204,7 +204,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) | |||
| 204 | } | 204 | } |
| 205 | path->name = malloc(MAX_EVENT_LENGTH); | 205 | path->name = malloc(MAX_EVENT_LENGTH); |
| 206 | if (!path->name) { | 206 | if (!path->name) { |
| 207 | free(path->system); | 207 | zfree(&path->system); |
| 208 | free(path); | 208 | free(path); |
| 209 | return NULL; | 209 | return NULL; |
| 210 | } | 210 | } |
| @@ -236,8 +236,8 @@ struct tracepoint_path *tracepoint_name_to_path(const char *name) | |||
| 236 | path->name = strdup(str+1); | 236 | path->name = strdup(str+1); |
| 237 | 237 | ||
| 238 | if (path->system == NULL || path->name == NULL) { | 238 | if (path->system == NULL || path->name == NULL) { |
| 239 | free(path->system); | 239 | zfree(&path->system); |
| 240 | free(path->name); | 240 | zfree(&path->name); |
| 241 | free(path); | 241 | free(path); |
| 242 | path = NULL; | 242 | path = NULL; |
| 243 | } | 243 | } |
| @@ -917,7 +917,7 @@ int parse_events_terms(struct list_head *terms, const char *str) | |||
| 917 | ret = parse_events__scanner(str, &data, PE_START_TERMS); | 917 | ret = parse_events__scanner(str, &data, PE_START_TERMS); |
| 918 | if (!ret) { | 918 | if (!ret) { |
| 919 | list_splice(data.terms, terms); | 919 | list_splice(data.terms, terms); |
| 920 | free(data.terms); | 920 | zfree(&data.terms); |
| 921 | return 0; | 921 | return 0; |
| 922 | } | 922 | } |
| 923 | 923 | ||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 56fc10a5e288..0934d645ebdc 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
| @@ -755,7 +755,7 @@ void print_pmu_events(const char *event_glob, bool name_only) | |||
| 755 | continue; | 755 | continue; |
| 756 | } | 756 | } |
| 757 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); | 757 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); |
| 758 | free(aliases[j]); | 758 | zfree(&aliases[j]); |
| 759 | printed++; | 759 | printed++; |
| 760 | } | 760 | } |
| 761 | if (printed) | 761 | if (printed) |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 544ac1898a9f..86ed8580c3cb 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -172,6 +172,52 @@ const char *kernel_get_module_path(const char *module) | |||
| 172 | return (dso) ? dso->long_name : NULL; | 172 | return (dso) ? dso->long_name : NULL; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | /* Copied from unwind.c */ | ||
| 176 | static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, | ||
| 177 | GElf_Shdr *shp, const char *name) | ||
| 178 | { | ||
| 179 | Elf_Scn *sec = NULL; | ||
| 180 | |||
| 181 | while ((sec = elf_nextscn(elf, sec)) != NULL) { | ||
| 182 | char *str; | ||
| 183 | |||
| 184 | gelf_getshdr(sec, shp); | ||
| 185 | str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); | ||
| 186 | if (!strcmp(name, str)) | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | |||
| 190 | return sec; | ||
| 191 | } | ||
| 192 | |||
| 193 | static int get_text_start_address(const char *exec, unsigned long *address) | ||
| 194 | { | ||
| 195 | Elf *elf; | ||
| 196 | GElf_Ehdr ehdr; | ||
| 197 | GElf_Shdr shdr; | ||
| 198 | int fd, ret = -ENOENT; | ||
| 199 | |||
| 200 | fd = open(exec, O_RDONLY); | ||
| 201 | if (fd < 0) | ||
| 202 | return -errno; | ||
| 203 | |||
| 204 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
| 205 | if (elf == NULL) | ||
| 206 | return -EINVAL; | ||
| 207 | |||
| 208 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
| 209 | goto out; | ||
| 210 | |||
| 211 | if (!elf_section_by_name(elf, &ehdr, &shdr, ".text")) | ||
| 212 | goto out; | ||
| 213 | |||
| 214 | *address = shdr.sh_addr - shdr.sh_offset; | ||
| 215 | ret = 0; | ||
| 216 | out: | ||
| 217 | elf_end(elf); | ||
| 218 | return ret; | ||
| 219 | } | ||
| 220 | |||
| 175 | static int init_user_exec(void) | 221 | static int init_user_exec(void) |
| 176 | { | 222 | { |
| 177 | int ret = 0; | 223 | int ret = 0; |
| @@ -186,6 +232,37 @@ static int init_user_exec(void) | |||
| 186 | return ret; | 232 | return ret; |
| 187 | } | 233 | } |
| 188 | 234 | ||
| 235 | static int convert_exec_to_group(const char *exec, char **result) | ||
| 236 | { | ||
| 237 | char *ptr1, *ptr2, *exec_copy; | ||
| 238 | char buf[64]; | ||
| 239 | int ret; | ||
| 240 | |||
| 241 | exec_copy = strdup(exec); | ||
| 242 | if (!exec_copy) | ||
| 243 | return -ENOMEM; | ||
| 244 | |||
| 245 | ptr1 = basename(exec_copy); | ||
| 246 | if (!ptr1) { | ||
| 247 | ret = -EINVAL; | ||
| 248 | goto out; | ||
| 249 | } | ||
| 250 | |||
| 251 | ptr2 = strpbrk(ptr1, "-._"); | ||
| 252 | if (ptr2) | ||
| 253 | *ptr2 = '\0'; | ||
| 254 | ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1); | ||
| 255 | if (ret < 0) | ||
| 256 | goto out; | ||
| 257 | |||
| 258 | *result = strdup(buf); | ||
| 259 | ret = *result ? 0 : -ENOMEM; | ||
| 260 | |||
| 261 | out: | ||
| 262 | free(exec_copy); | ||
| 263 | return ret; | ||
| 264 | } | ||
| 265 | |||
| 189 | static int convert_to_perf_probe_point(struct probe_trace_point *tp, | 266 | static int convert_to_perf_probe_point(struct probe_trace_point *tp, |
| 190 | struct perf_probe_point *pp) | 267 | struct perf_probe_point *pp) |
| 191 | { | 268 | { |
| @@ -261,6 +338,40 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, | |||
| 261 | return 0; | 338 | return 0; |
| 262 | } | 339 | } |
| 263 | 340 | ||
| 341 | static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, | ||
| 342 | int ntevs, const char *exec) | ||
| 343 | { | ||
| 344 | int i, ret = 0; | ||
| 345 | unsigned long offset, stext = 0; | ||
| 346 | char buf[32]; | ||
| 347 | |||
| 348 | if (!exec) | ||
| 349 | return 0; | ||
| 350 | |||
| 351 | ret = get_text_start_address(exec, &stext); | ||
| 352 | if (ret < 0) | ||
| 353 | return ret; | ||
| 354 | |||
| 355 | for (i = 0; i < ntevs && ret >= 0; i++) { | ||
| 356 | offset = tevs[i].point.address - stext; | ||
| 357 | offset += tevs[i].point.offset; | ||
| 358 | tevs[i].point.offset = 0; | ||
| 359 | zfree(&tevs[i].point.symbol); | ||
| 360 | ret = e_snprintf(buf, 32, "0x%lx", offset); | ||
| 361 | if (ret < 0) | ||
| 362 | break; | ||
| 363 | tevs[i].point.module = strdup(exec); | ||
| 364 | tevs[i].point.symbol = strdup(buf); | ||
| 365 | if (!tevs[i].point.symbol || !tevs[i].point.module) { | ||
| 366 | ret = -ENOMEM; | ||
| 367 | break; | ||
| 368 | } | ||
| 369 | tevs[i].uprobes = true; | ||
| 370 | } | ||
| 371 | |||
| 372 | return ret; | ||
| 373 | } | ||
| 374 | |||
| 264 | static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, | 375 | static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, |
| 265 | int ntevs, const char *module) | 376 | int ntevs, const char *module) |
| 266 | { | 377 | { |
| @@ -290,9 +401,7 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, | |||
| 290 | } | 401 | } |
| 291 | } | 402 | } |
| 292 | 403 | ||
| 293 | if (tmp) | 404 | free(tmp); |
| 294 | free(tmp); | ||
| 295 | |||
| 296 | return ret; | 405 | return ret; |
| 297 | } | 406 | } |
| 298 | 407 | ||
| @@ -305,15 +414,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
| 305 | struct debuginfo *dinfo; | 414 | struct debuginfo *dinfo; |
| 306 | int ntevs, ret = 0; | 415 | int ntevs, ret = 0; |
| 307 | 416 | ||
| 308 | if (pev->uprobes) { | ||
| 309 | if (need_dwarf) { | ||
| 310 | pr_warning("Debuginfo-analysis is not yet supported" | ||
| 311 | " with -x/--exec option.\n"); | ||
| 312 | return -ENOSYS; | ||
| 313 | } | ||
| 314 | return convert_name_to_addr(pev, target); | ||
| 315 | } | ||
| 316 | |||
| 317 | dinfo = open_debuginfo(target); | 417 | dinfo = open_debuginfo(target); |
| 318 | 418 | ||
| 319 | if (!dinfo) { | 419 | if (!dinfo) { |
| @@ -332,9 +432,14 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
| 332 | 432 | ||
| 333 | if (ntevs > 0) { /* Succeeded to find trace events */ | 433 | if (ntevs > 0) { /* Succeeded to find trace events */ |
| 334 | pr_debug("find %d probe_trace_events.\n", ntevs); | 434 | pr_debug("find %d probe_trace_events.\n", ntevs); |
| 335 | if (target) | 435 | if (target) { |
| 336 | ret = add_module_to_probe_trace_events(*tevs, ntevs, | 436 | if (pev->uprobes) |
| 337 | target); | 437 | ret = add_exec_to_probe_trace_events(*tevs, |
| 438 | ntevs, target); | ||
| 439 | else | ||
| 440 | ret = add_module_to_probe_trace_events(*tevs, | ||
| 441 | ntevs, target); | ||
| 442 | } | ||
| 338 | return ret < 0 ? ret : ntevs; | 443 | return ret < 0 ? ret : ntevs; |
| 339 | } | 444 | } |
| 340 | 445 | ||
| @@ -401,15 +506,13 @@ static int get_real_path(const char *raw_path, const char *comp_dir, | |||
| 401 | case EFAULT: | 506 | case EFAULT: |
| 402 | raw_path = strchr(++raw_path, '/'); | 507 | raw_path = strchr(++raw_path, '/'); |
| 403 | if (!raw_path) { | 508 | if (!raw_path) { |
| 404 | free(*new_path); | 509 | zfree(new_path); |
| 405 | *new_path = NULL; | ||
| 406 | return -ENOENT; | 510 | return -ENOENT; |
| 407 | } | 511 | } |
| 408 | continue; | 512 | continue; |
| 409 | 513 | ||
| 410 | default: | 514 | default: |
| 411 | free(*new_path); | 515 | zfree(new_path); |
| 412 | *new_path = NULL; | ||
| 413 | return -errno; | 516 | return -errno; |
| 414 | } | 517 | } |
| 415 | } | 518 | } |
| @@ -580,7 +683,7 @@ static int show_available_vars_at(struct debuginfo *dinfo, | |||
| 580 | */ | 683 | */ |
| 581 | fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, | 684 | fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, |
| 582 | vl->point.offset); | 685 | vl->point.offset); |
| 583 | free(vl->point.symbol); | 686 | zfree(&vl->point.symbol); |
| 584 | nvars = 0; | 687 | nvars = 0; |
| 585 | if (vl->vars) { | 688 | if (vl->vars) { |
| 586 | strlist__for_each(node, vl->vars) { | 689 | strlist__for_each(node, vl->vars) { |
| @@ -654,9 +757,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
| 654 | return -ENOSYS; | 757 | return -ENOSYS; |
| 655 | } | 758 | } |
| 656 | 759 | ||
| 657 | if (pev->uprobes) | ||
| 658 | return convert_name_to_addr(pev, target); | ||
| 659 | |||
| 660 | return 0; | 760 | return 0; |
| 661 | } | 761 | } |
| 662 | 762 | ||
| @@ -1278,8 +1378,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) | |||
| 1278 | error: | 1378 | error: |
| 1279 | pr_debug("Failed to synthesize perf probe point: %s\n", | 1379 | pr_debug("Failed to synthesize perf probe point: %s\n", |
| 1280 | strerror(-ret)); | 1380 | strerror(-ret)); |
| 1281 | if (buf) | 1381 | free(buf); |
| 1282 | free(buf); | ||
| 1283 | return NULL; | 1382 | return NULL; |
| 1284 | } | 1383 | } |
| 1285 | 1384 | ||
| @@ -1480,34 +1579,25 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
| 1480 | struct perf_probe_arg_field *field, *next; | 1579 | struct perf_probe_arg_field *field, *next; |
| 1481 | int i; | 1580 | int i; |
| 1482 | 1581 | ||
| 1483 | if (pev->event) | 1582 | free(pev->event); |
| 1484 | free(pev->event); | 1583 | free(pev->group); |
| 1485 | if (pev->group) | 1584 | free(pp->file); |
| 1486 | free(pev->group); | 1585 | free(pp->function); |
| 1487 | if (pp->file) | 1586 | free(pp->lazy_line); |
| 1488 | free(pp->file); | 1587 | |
| 1489 | if (pp->function) | ||
| 1490 | free(pp->function); | ||
| 1491 | if (pp->lazy_line) | ||
| 1492 | free(pp->lazy_line); | ||
| 1493 | for (i = 0; i < pev->nargs; i++) { | 1588 | for (i = 0; i < pev->nargs; i++) { |
| 1494 | if (pev->args[i].name) | 1589 | free(pev->args[i].name); |
| 1495 | free(pev->args[i].name); | 1590 | free(pev->args[i].var); |
| 1496 | if (pev->args[i].var) | 1591 | free(pev->args[i].type); |
| 1497 | free(pev->args[i].var); | ||
| 1498 | if (pev->args[i].type) | ||
| 1499 | free(pev->args[i].type); | ||
| 1500 | field = pev->args[i].field; | 1592 | field = pev->args[i].field; |
| 1501 | while (field) { | 1593 | while (field) { |
| 1502 | next = field->next; | 1594 | next = field->next; |
| 1503 | if (field->name) | 1595 | zfree(&field->name); |
| 1504 | free(field->name); | ||
| 1505 | free(field); | 1596 | free(field); |
| 1506 | field = next; | 1597 | field = next; |
| 1507 | } | 1598 | } |
| 1508 | } | 1599 | } |
| 1509 | if (pev->args) | 1600 | free(pev->args); |
| 1510 | free(pev->args); | ||
| 1511 | memset(pev, 0, sizeof(*pev)); | 1601 | memset(pev, 0, sizeof(*pev)); |
| 1512 | } | 1602 | } |
| 1513 | 1603 | ||
| @@ -1516,21 +1606,14 @@ static void clear_probe_trace_event(struct probe_trace_event *tev) | |||
| 1516 | struct probe_trace_arg_ref *ref, *next; | 1606 | struct probe_trace_arg_ref *ref, *next; |
| 1517 | int i; | 1607 | int i; |
| 1518 | 1608 | ||
| 1519 | if (tev->event) | 1609 | free(tev->event); |
| 1520 | free(tev->event); | 1610 | free(tev->group); |
| 1521 | if (tev->group) | 1611 | free(tev->point.symbol); |
| 1522 | free(tev->group); | 1612 | free(tev->point.module); |
| 1523 | if (tev->point.symbol) | ||
| 1524 | free(tev->point.symbol); | ||
| 1525 | if (tev->point.module) | ||
| 1526 | free(tev->point.module); | ||
| 1527 | for (i = 0; i < tev->nargs; i++) { | 1613 | for (i = 0; i < tev->nargs; i++) { |
| 1528 | if (tev->args[i].name) | 1614 | free(tev->args[i].name); |
| 1529 | free(tev->args[i].name); | 1615 | free(tev->args[i].value); |
| 1530 | if (tev->args[i].value) | 1616 | free(tev->args[i].type); |
| 1531 | free(tev->args[i].value); | ||
| 1532 | if (tev->args[i].type) | ||
| 1533 | free(tev->args[i].type); | ||
| 1534 | ref = tev->args[i].ref; | 1617 | ref = tev->args[i].ref; |
| 1535 | while (ref) { | 1618 | while (ref) { |
| 1536 | next = ref->next; | 1619 | next = ref->next; |
| @@ -1538,8 +1621,7 @@ static void clear_probe_trace_event(struct probe_trace_event *tev) | |||
| 1538 | ref = next; | 1621 | ref = next; |
| 1539 | } | 1622 | } |
| 1540 | } | 1623 | } |
| 1541 | if (tev->args) | 1624 | free(tev->args); |
| 1542 | free(tev->args); | ||
| 1543 | memset(tev, 0, sizeof(*tev)); | 1625 | memset(tev, 0, sizeof(*tev)); |
| 1544 | } | 1626 | } |
| 1545 | 1627 | ||
| @@ -1913,14 +1995,29 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, | |||
| 1913 | int max_tevs, const char *target) | 1995 | int max_tevs, const char *target) |
| 1914 | { | 1996 | { |
| 1915 | struct symbol *sym; | 1997 | struct symbol *sym; |
| 1916 | int ret = 0, i; | 1998 | int ret, i; |
| 1917 | struct probe_trace_event *tev; | 1999 | struct probe_trace_event *tev; |
| 1918 | 2000 | ||
| 2001 | if (pev->uprobes && !pev->group) { | ||
| 2002 | /* Replace group name if not given */ | ||
| 2003 | ret = convert_exec_to_group(target, &pev->group); | ||
| 2004 | if (ret != 0) { | ||
| 2005 | pr_warning("Failed to make a group name.\n"); | ||
| 2006 | return ret; | ||
| 2007 | } | ||
| 2008 | } | ||
| 2009 | |||
| 1919 | /* Convert perf_probe_event with debuginfo */ | 2010 | /* Convert perf_probe_event with debuginfo */ |
| 1920 | ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); | 2011 | ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); |
| 1921 | if (ret != 0) | 2012 | if (ret != 0) |
| 1922 | return ret; /* Found in debuginfo or got an error */ | 2013 | return ret; /* Found in debuginfo or got an error */ |
| 1923 | 2014 | ||
| 2015 | if (pev->uprobes) { | ||
| 2016 | ret = convert_name_to_addr(pev, target); | ||
| 2017 | if (ret < 0) | ||
| 2018 | return ret; | ||
| 2019 | } | ||
| 2020 | |||
| 1924 | /* Allocate trace event buffer */ | 2021 | /* Allocate trace event buffer */ |
| 1925 | tev = *tevs = zalloc(sizeof(struct probe_trace_event)); | 2022 | tev = *tevs = zalloc(sizeof(struct probe_trace_event)); |
| 1926 | if (tev == NULL) | 2023 | if (tev == NULL) |
| @@ -2056,7 +2153,7 @@ end: | |||
| 2056 | for (i = 0; i < npevs; i++) { | 2153 | for (i = 0; i < npevs; i++) { |
| 2057 | for (j = 0; j < pkgs[i].ntevs; j++) | 2154 | for (j = 0; j < pkgs[i].ntevs; j++) |
| 2058 | clear_probe_trace_event(&pkgs[i].tevs[j]); | 2155 | clear_probe_trace_event(&pkgs[i].tevs[j]); |
| 2059 | free(pkgs[i].tevs); | 2156 | zfree(&pkgs[i].tevs); |
| 2060 | } | 2157 | } |
| 2061 | free(pkgs); | 2158 | free(pkgs); |
| 2062 | 2159 | ||
| @@ -2281,7 +2378,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) | |||
| 2281 | struct perf_probe_point *pp = &pev->point; | 2378 | struct perf_probe_point *pp = &pev->point; |
| 2282 | struct symbol *sym; | 2379 | struct symbol *sym; |
| 2283 | struct map *map = NULL; | 2380 | struct map *map = NULL; |
| 2284 | char *function = NULL, *name = NULL; | 2381 | char *function = NULL; |
| 2285 | int ret = -EINVAL; | 2382 | int ret = -EINVAL; |
| 2286 | unsigned long long vaddr = 0; | 2383 | unsigned long long vaddr = 0; |
| 2287 | 2384 | ||
| @@ -2297,12 +2394,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) | |||
| 2297 | goto out; | 2394 | goto out; |
| 2298 | } | 2395 | } |
| 2299 | 2396 | ||
| 2300 | name = realpath(exec, NULL); | 2397 | map = dso__new_map(exec); |
| 2301 | if (!name) { | ||
| 2302 | pr_warning("Cannot find realpath for %s.\n", exec); | ||
| 2303 | goto out; | ||
| 2304 | } | ||
| 2305 | map = dso__new_map(name); | ||
| 2306 | if (!map) { | 2398 | if (!map) { |
| 2307 | pr_warning("Cannot find appropriate DSO for %s.\n", exec); | 2399 | pr_warning("Cannot find appropriate DSO for %s.\n", exec); |
| 2308 | goto out; | 2400 | goto out; |
| @@ -2367,7 +2459,5 @@ out: | |||
| 2367 | } | 2459 | } |
| 2368 | if (function) | 2460 | if (function) |
| 2369 | free(function); | 2461 | free(function); |
| 2370 | if (name) | ||
| 2371 | free(name); | ||
| 2372 | return ret; | 2462 | return ret; |
| 2373 | } | 2463 | } |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index f9f3de8b4220..d481c46e0796 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
| @@ -12,6 +12,7 @@ struct probe_trace_point { | |||
| 12 | char *symbol; /* Base symbol */ | 12 | char *symbol; /* Base symbol */ |
| 13 | char *module; /* Module name */ | 13 | char *module; /* Module name */ |
| 14 | unsigned long offset; /* Offset from symbol */ | 14 | unsigned long offset; /* Offset from symbol */ |
| 15 | unsigned long address; /* Actual address of the trace point */ | ||
| 15 | bool retprobe; /* Return probe flag */ | 16 | bool retprobe; /* Return probe flag */ |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index ffb657ffd327..061edb162b5b 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
| @@ -226,10 +226,8 @@ struct debuginfo *debuginfo__new(const char *path) | |||
| 226 | if (!dbg) | 226 | if (!dbg) |
| 227 | return NULL; | 227 | return NULL; |
| 228 | 228 | ||
| 229 | if (debuginfo__init_offline_dwarf(dbg, path) < 0) { | 229 | if (debuginfo__init_offline_dwarf(dbg, path) < 0) |
| 230 | free(dbg); | 230 | zfree(&dbg); |
| 231 | dbg = NULL; | ||
| 232 | } | ||
| 233 | 231 | ||
| 234 | return dbg; | 232 | return dbg; |
| 235 | } | 233 | } |
| @@ -241,10 +239,8 @@ struct debuginfo *debuginfo__new_online_kernel(unsigned long addr) | |||
| 241 | if (!dbg) | 239 | if (!dbg) |
| 242 | return NULL; | 240 | return NULL; |
| 243 | 241 | ||
| 244 | if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) { | 242 | if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) |
| 245 | free(dbg); | 243 | zfree(&dbg); |
| 246 | dbg = NULL; | ||
| 247 | } | ||
| 248 | 244 | ||
| 249 | return dbg; | 245 | return dbg; |
| 250 | } | 246 | } |
| @@ -729,6 +725,7 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, | |||
| 729 | return -ENOENT; | 725 | return -ENOENT; |
| 730 | } | 726 | } |
| 731 | tp->offset = (unsigned long)(paddr - sym.st_value); | 727 | tp->offset = (unsigned long)(paddr - sym.st_value); |
| 728 | tp->address = (unsigned long)paddr; | ||
| 732 | tp->symbol = strdup(symbol); | 729 | tp->symbol = strdup(symbol); |
| 733 | if (!tp->symbol) | 730 | if (!tp->symbol) |
| 734 | return -ENOMEM; | 731 | return -ENOMEM; |
| @@ -1301,8 +1298,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg, | |||
| 1301 | 1298 | ||
| 1302 | ret = debuginfo__find_probes(dbg, &tf.pf); | 1299 | ret = debuginfo__find_probes(dbg, &tf.pf); |
| 1303 | if (ret < 0) { | 1300 | if (ret < 0) { |
| 1304 | free(*tevs); | 1301 | zfree(tevs); |
| 1305 | *tevs = NULL; | ||
| 1306 | return ret; | 1302 | return ret; |
| 1307 | } | 1303 | } |
| 1308 | 1304 | ||
| @@ -1413,13 +1409,10 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg, | |||
| 1413 | if (ret < 0) { | 1409 | if (ret < 0) { |
| 1414 | /* Free vlist for error */ | 1410 | /* Free vlist for error */ |
| 1415 | while (af.nvls--) { | 1411 | while (af.nvls--) { |
| 1416 | if (af.vls[af.nvls].point.symbol) | 1412 | zfree(&af.vls[af.nvls].point.symbol); |
| 1417 | free(af.vls[af.nvls].point.symbol); | 1413 | strlist__delete(af.vls[af.nvls].vars); |
| 1418 | if (af.vls[af.nvls].vars) | ||
| 1419 | strlist__delete(af.vls[af.nvls].vars); | ||
| 1420 | } | 1414 | } |
| 1421 | free(af.vls); | 1415 | zfree(vls); |
| 1422 | *vls = NULL; | ||
| 1423 | return ret; | 1416 | return ret; |
| 1424 | } | 1417 | } |
| 1425 | 1418 | ||
| @@ -1523,10 +1516,7 @@ post: | |||
| 1523 | if (fname) { | 1516 | if (fname) { |
| 1524 | ppt->file = strdup(fname); | 1517 | ppt->file = strdup(fname); |
| 1525 | if (ppt->file == NULL) { | 1518 | if (ppt->file == NULL) { |
| 1526 | if (ppt->function) { | 1519 | zfree(&ppt->function); |
| 1527 | free(ppt->function); | ||
| 1528 | ppt->function = NULL; | ||
| 1529 | } | ||
| 1530 | ret = -ENOMEM; | 1520 | ret = -ENOMEM; |
| 1531 | goto end; | 1521 | goto end; |
| 1532 | } | 1522 | } |
| @@ -1580,8 +1570,7 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) | |||
| 1580 | else | 1570 | else |
| 1581 | ret = 0; /* Lines are not found */ | 1571 | ret = 0; /* Lines are not found */ |
| 1582 | else { | 1572 | else { |
| 1583 | free(lf->lr->path); | 1573 | zfree(&lf->lr->path); |
| 1584 | lf->lr->path = NULL; | ||
| 1585 | } | 1574 | } |
| 1586 | return ret; | 1575 | return ret; |
| 1587 | } | 1576 | } |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index e5104538c354..104a47563d39 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
| @@ -74,8 +74,7 @@ bool perf_can_sample_identifier(void) | |||
| 74 | return perf_probe_api(perf_probe_sample_identifier); | 74 | return perf_probe_api(perf_probe_sample_identifier); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | void perf_evlist__config(struct perf_evlist *evlist, | 77 | void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) |
| 78 | struct perf_record_opts *opts) | ||
| 79 | { | 78 | { |
| 80 | struct perf_evsel *evsel; | 79 | struct perf_evsel *evsel; |
| 81 | bool use_sample_identifier = false; | 80 | bool use_sample_identifier = false; |
| @@ -123,7 +122,7 @@ static int get_max_rate(unsigned int *rate) | |||
| 123 | return filename__read_int(path, (int *) rate); | 122 | return filename__read_int(path, (int *) rate); |
| 124 | } | 123 | } |
| 125 | 124 | ||
| 126 | static int perf_record_opts__config_freq(struct perf_record_opts *opts) | 125 | static int record_opts__config_freq(struct record_opts *opts) |
| 127 | { | 126 | { |
| 128 | bool user_freq = opts->user_freq != UINT_MAX; | 127 | bool user_freq = opts->user_freq != UINT_MAX; |
| 129 | unsigned int max_rate; | 128 | unsigned int max_rate; |
| @@ -173,9 +172,9 @@ static int perf_record_opts__config_freq(struct perf_record_opts *opts) | |||
| 173 | return 0; | 172 | return 0; |
| 174 | } | 173 | } |
| 175 | 174 | ||
| 176 | int perf_record_opts__config(struct perf_record_opts *opts) | 175 | int record_opts__config(struct record_opts *opts) |
| 177 | { | 176 | { |
| 178 | return perf_record_opts__config_freq(opts); | 177 | return record_opts__config_freq(opts); |
| 179 | } | 178 | } |
| 180 | 179 | ||
| 181 | bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) | 180 | bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) |
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index d5e5969f6fea..e108207c5de0 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
| @@ -194,8 +194,7 @@ static void define_event_symbols(struct event_format *event, | |||
| 194 | zero_flag_atom = 0; | 194 | zero_flag_atom = 0; |
| 195 | break; | 195 | break; |
| 196 | case PRINT_FIELD: | 196 | case PRINT_FIELD: |
| 197 | if (cur_field_name) | 197 | free(cur_field_name); |
| 198 | free(cur_field_name); | ||
| 199 | cur_field_name = strdup(args->field.name); | 198 | cur_field_name = strdup(args->field.name); |
| 200 | break; | 199 | break; |
| 201 | case PRINT_FLAGS: | 200 | case PRINT_FLAGS: |
| @@ -257,12 +256,9 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel) | |||
| 257 | return event; | 256 | return event; |
| 258 | } | 257 | } |
| 259 | 258 | ||
| 260 | static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, | 259 | static void perl_process_tracepoint(struct perf_sample *sample, |
| 261 | struct perf_sample *sample, | ||
| 262 | struct perf_evsel *evsel, | 260 | struct perf_evsel *evsel, |
| 263 | struct machine *machine __maybe_unused, | 261 | struct thread *thread) |
| 264 | struct thread *thread, | ||
| 265 | struct addr_location *al) | ||
| 266 | { | 262 | { |
| 267 | struct format_field *field; | 263 | struct format_field *field; |
| 268 | static char handler[256]; | 264 | static char handler[256]; |
| @@ -349,10 +345,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, | |||
| 349 | 345 | ||
| 350 | static void perl_process_event_generic(union perf_event *event, | 346 | static void perl_process_event_generic(union perf_event *event, |
| 351 | struct perf_sample *sample, | 347 | struct perf_sample *sample, |
| 352 | struct perf_evsel *evsel, | 348 | struct perf_evsel *evsel) |
| 353 | struct machine *machine __maybe_unused, | ||
| 354 | struct thread *thread __maybe_unused, | ||
| 355 | struct addr_location *al __maybe_unused) | ||
| 356 | { | 349 | { |
| 357 | dSP; | 350 | dSP; |
| 358 | 351 | ||
| @@ -377,12 +370,11 @@ static void perl_process_event_generic(union perf_event *event, | |||
| 377 | static void perl_process_event(union perf_event *event, | 370 | static void perl_process_event(union perf_event *event, |
| 378 | struct perf_sample *sample, | 371 | struct perf_sample *sample, |
| 379 | struct perf_evsel *evsel, | 372 | struct perf_evsel *evsel, |
| 380 | struct machine *machine, | ||
| 381 | struct thread *thread, | 373 | struct thread *thread, |
| 382 | struct addr_location *al) | 374 | struct addr_location *al __maybe_unused) |
| 383 | { | 375 | { |
| 384 | perl_process_tracepoint(event, sample, evsel, machine, thread, al); | 376 | perl_process_tracepoint(sample, evsel, thread); |
| 385 | perl_process_event_generic(event, sample, evsel, machine, thread, al); | 377 | perl_process_event_generic(event, sample, evsel); |
| 386 | } | 378 | } |
| 387 | 379 | ||
| 388 | static void run_start_sub(void) | 380 | static void run_start_sub(void) |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 53c20e7fd900..cd9774df3750 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
| @@ -161,8 +161,7 @@ static void define_event_symbols(struct event_format *event, | |||
| 161 | zero_flag_atom = 0; | 161 | zero_flag_atom = 0; |
| 162 | break; | 162 | break; |
| 163 | case PRINT_FIELD: | 163 | case PRINT_FIELD: |
| 164 | if (cur_field_name) | 164 | free(cur_field_name); |
| 165 | free(cur_field_name); | ||
| 166 | cur_field_name = strdup(args->field.name); | 165 | cur_field_name = strdup(args->field.name); |
| 167 | break; | 166 | break; |
| 168 | case PRINT_FLAGS: | 167 | case PRINT_FLAGS: |
| @@ -231,13 +230,10 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel) | |||
| 231 | return event; | 230 | return event; |
| 232 | } | 231 | } |
| 233 | 232 | ||
| 234 | static void python_process_tracepoint(union perf_event *perf_event | 233 | static void python_process_tracepoint(struct perf_sample *sample, |
| 235 | __maybe_unused, | 234 | struct perf_evsel *evsel, |
| 236 | struct perf_sample *sample, | 235 | struct thread *thread, |
| 237 | struct perf_evsel *evsel, | 236 | struct addr_location *al) |
| 238 | struct machine *machine __maybe_unused, | ||
| 239 | struct thread *thread, | ||
| 240 | struct addr_location *al) | ||
| 241 | { | 237 | { |
| 242 | PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; | 238 | PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; |
| 243 | static char handler_name[256]; | 239 | static char handler_name[256]; |
| @@ -351,11 +347,8 @@ static void python_process_tracepoint(union perf_event *perf_event | |||
| 351 | Py_DECREF(t); | 347 | Py_DECREF(t); |
| 352 | } | 348 | } |
| 353 | 349 | ||
| 354 | static void python_process_general_event(union perf_event *perf_event | 350 | static void python_process_general_event(struct perf_sample *sample, |
| 355 | __maybe_unused, | ||
| 356 | struct perf_sample *sample, | ||
| 357 | struct perf_evsel *evsel, | 351 | struct perf_evsel *evsel, |
| 358 | struct machine *machine __maybe_unused, | ||
| 359 | struct thread *thread, | 352 | struct thread *thread, |
| 360 | struct addr_location *al) | 353 | struct addr_location *al) |
| 361 | { | 354 | { |
| @@ -411,22 +404,19 @@ exit: | |||
| 411 | Py_DECREF(t); | 404 | Py_DECREF(t); |
| 412 | } | 405 | } |
| 413 | 406 | ||
| 414 | static void python_process_event(union perf_event *perf_event, | 407 | static void python_process_event(union perf_event *event __maybe_unused, |
| 415 | struct perf_sample *sample, | 408 | struct perf_sample *sample, |
| 416 | struct perf_evsel *evsel, | 409 | struct perf_evsel *evsel, |
| 417 | struct machine *machine, | ||
| 418 | struct thread *thread, | 410 | struct thread *thread, |
| 419 | struct addr_location *al) | 411 | struct addr_location *al) |
| 420 | { | 412 | { |
| 421 | switch (evsel->attr.type) { | 413 | switch (evsel->attr.type) { |
| 422 | case PERF_TYPE_TRACEPOINT: | 414 | case PERF_TYPE_TRACEPOINT: |
| 423 | python_process_tracepoint(perf_event, sample, evsel, | 415 | python_process_tracepoint(sample, evsel, thread, al); |
| 424 | machine, thread, al); | ||
| 425 | break; | 416 | break; |
| 426 | /* Reserve for future process_hw/sw/raw APIs */ | 417 | /* Reserve for future process_hw/sw/raw APIs */ |
| 427 | default: | 418 | default: |
| 428 | python_process_general_event(perf_event, sample, evsel, | 419 | python_process_general_event(sample, evsel, thread, al); |
| 429 | machine, thread, al); | ||
| 430 | } | 420 | } |
| 431 | } | 421 | } |
| 432 | 422 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 989b2e377626..8ffe29c55d0f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -132,18 +132,18 @@ static void perf_session__delete_threads(struct perf_session *session) | |||
| 132 | 132 | ||
| 133 | static void perf_session_env__delete(struct perf_session_env *env) | 133 | static void perf_session_env__delete(struct perf_session_env *env) |
| 134 | { | 134 | { |
| 135 | free(env->hostname); | 135 | zfree(&env->hostname); |
| 136 | free(env->os_release); | 136 | zfree(&env->os_release); |
| 137 | free(env->version); | 137 | zfree(&env->version); |
| 138 | free(env->arch); | 138 | zfree(&env->arch); |
| 139 | free(env->cpu_desc); | 139 | zfree(&env->cpu_desc); |
| 140 | free(env->cpuid); | 140 | zfree(&env->cpuid); |
| 141 | 141 | ||
| 142 | free(env->cmdline); | 142 | zfree(&env->cmdline); |
| 143 | free(env->sibling_cores); | 143 | zfree(&env->sibling_cores); |
| 144 | free(env->sibling_threads); | 144 | zfree(&env->sibling_threads); |
| 145 | free(env->numa_nodes); | 145 | zfree(&env->numa_nodes); |
| 146 | free(env->pmu_mappings); | 146 | zfree(&env->pmu_mappings); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | void perf_session__delete(struct perf_session *session) | 149 | void perf_session__delete(struct perf_session *session) |
| @@ -830,6 +830,7 @@ static struct machine * | |||
| 830 | struct perf_sample *sample) | 830 | struct perf_sample *sample) |
| 831 | { | 831 | { |
| 832 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 832 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
| 833 | struct machine *machine; | ||
| 833 | 834 | ||
| 834 | if (perf_guest && | 835 | if (perf_guest && |
| 835 | ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || | 836 | ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || |
| @@ -842,7 +843,11 @@ static struct machine * | |||
| 842 | else | 843 | else |
| 843 | pid = sample->pid; | 844 | pid = sample->pid; |
| 844 | 845 | ||
| 845 | return perf_session__findnew_machine(session, pid); | 846 | machine = perf_session__find_machine(session, pid); |
| 847 | if (!machine) | ||
| 848 | machine = perf_session__findnew_machine(session, | ||
| 849 | DEFAULT_GUEST_KERNEL_ID); | ||
| 850 | return machine; | ||
| 846 | } | 851 | } |
| 847 | 852 | ||
| 848 | return &session->machines.host; | 853 | return &session->machines.host; |
| @@ -1467,7 +1472,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
| 1467 | } | 1472 | } |
| 1468 | 1473 | ||
| 1469 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, | 1474 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, |
| 1470 | struct machine *machine, struct addr_location *al, | 1475 | struct addr_location *al, |
| 1471 | unsigned int print_opts, unsigned int stack_depth) | 1476 | unsigned int print_opts, unsigned int stack_depth) |
| 1472 | { | 1477 | { |
| 1473 | struct callchain_cursor_node *node; | 1478 | struct callchain_cursor_node *node; |
| @@ -1482,7 +1487,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, | |||
| 1482 | if (symbol_conf.use_callchain && sample->callchain) { | 1487 | if (symbol_conf.use_callchain && sample->callchain) { |
| 1483 | struct addr_location node_al; | 1488 | struct addr_location node_al; |
| 1484 | 1489 | ||
| 1485 | if (machine__resolve_callchain(machine, evsel, al->thread, | 1490 | if (machine__resolve_callchain(al->machine, evsel, al->thread, |
| 1486 | sample, NULL, NULL, | 1491 | sample, NULL, NULL, |
| 1487 | PERF_MAX_STACK_DEPTH) != 0) { | 1492 | PERF_MAX_STACK_DEPTH) != 0) { |
| 1488 | if (verbose) | 1493 | if (verbose) |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 9c25d49900af..3140f8ae6148 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -106,7 +106,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
| 106 | unsigned int type); | 106 | unsigned int type); |
| 107 | 107 | ||
| 108 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, | 108 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, |
| 109 | struct machine *machine, struct addr_location *al, | 109 | struct addr_location *al, |
| 110 | unsigned int print_opts, unsigned int stack_depth); | 110 | unsigned int print_opts, unsigned int stack_depth); |
| 111 | 111 | ||
| 112 | int perf_session__cpu_bitmap(struct perf_session *session, | 112 | int perf_session__cpu_bitmap(struct perf_session *session, |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 8b0bb1f4494a..635cd8f8b22e 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
| @@ -13,6 +13,7 @@ int have_ignore_callees = 0; | |||
| 13 | int sort__need_collapse = 0; | 13 | int sort__need_collapse = 0; |
| 14 | int sort__has_parent = 0; | 14 | int sort__has_parent = 0; |
| 15 | int sort__has_sym = 0; | 15 | int sort__has_sym = 0; |
| 16 | int sort__has_dso = 0; | ||
| 16 | enum sort_mode sort__mode = SORT_MODE__NORMAL; | 17 | enum sort_mode sort__mode = SORT_MODE__NORMAL; |
| 17 | 18 | ||
| 18 | enum sort_type sort__first_dimension; | 19 | enum sort_type sort__first_dimension; |
| @@ -161,6 +162,11 @@ struct sort_entry sort_dso = { | |||
| 161 | 162 | ||
| 162 | /* --sort symbol */ | 163 | /* --sort symbol */ |
| 163 | 164 | ||
| 165 | static int64_t _sort__addr_cmp(u64 left_ip, u64 right_ip) | ||
| 166 | { | ||
| 167 | return (int64_t)(right_ip - left_ip); | ||
| 168 | } | ||
| 169 | |||
| 164 | static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r) | 170 | static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r) |
| 165 | { | 171 | { |
| 166 | u64 ip_l, ip_r; | 172 | u64 ip_l, ip_r; |
| @@ -183,15 +189,17 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 183 | int64_t ret; | 189 | int64_t ret; |
| 184 | 190 | ||
| 185 | if (!left->ms.sym && !right->ms.sym) | 191 | if (!left->ms.sym && !right->ms.sym) |
| 186 | return right->level - left->level; | 192 | return _sort__addr_cmp(left->ip, right->ip); |
| 187 | 193 | ||
| 188 | /* | 194 | /* |
| 189 | * comparing symbol address alone is not enough since it's a | 195 | * comparing symbol address alone is not enough since it's a |
| 190 | * relative address within a dso. | 196 | * relative address within a dso. |
| 191 | */ | 197 | */ |
| 192 | ret = sort__dso_cmp(left, right); | 198 | if (!sort__has_dso) { |
| 193 | if (ret != 0) | 199 | ret = sort__dso_cmp(left, right); |
| 194 | return ret; | 200 | if (ret != 0) |
| 201 | return ret; | ||
| 202 | } | ||
| 195 | 203 | ||
| 196 | return _sort__sym_cmp(left->ms.sym, right->ms.sym); | 204 | return _sort__sym_cmp(left->ms.sym, right->ms.sym); |
| 197 | } | 205 | } |
| @@ -372,7 +380,7 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 372 | struct addr_map_symbol *from_r = &right->branch_info->from; | 380 | struct addr_map_symbol *from_r = &right->branch_info->from; |
| 373 | 381 | ||
| 374 | if (!from_l->sym && !from_r->sym) | 382 | if (!from_l->sym && !from_r->sym) |
| 375 | return right->level - left->level; | 383 | return _sort__addr_cmp(from_l->addr, from_r->addr); |
| 376 | 384 | ||
| 377 | return _sort__sym_cmp(from_l->sym, from_r->sym); | 385 | return _sort__sym_cmp(from_l->sym, from_r->sym); |
| 378 | } | 386 | } |
| @@ -384,7 +392,7 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 384 | struct addr_map_symbol *to_r = &right->branch_info->to; | 392 | struct addr_map_symbol *to_r = &right->branch_info->to; |
| 385 | 393 | ||
| 386 | if (!to_l->sym && !to_r->sym) | 394 | if (!to_l->sym && !to_r->sym) |
| 387 | return right->level - left->level; | 395 | return _sort__addr_cmp(to_l->addr, to_r->addr); |
| 388 | 396 | ||
| 389 | return _sort__sym_cmp(to_l->sym, to_r->sym); | 397 | return _sort__sym_cmp(to_l->sym, to_r->sym); |
| 390 | } | 398 | } |
| @@ -1056,6 +1064,8 @@ int sort_dimension__add(const char *tok) | |||
| 1056 | sort__has_parent = 1; | 1064 | sort__has_parent = 1; |
| 1057 | } else if (sd->entry == &sort_sym) { | 1065 | } else if (sd->entry == &sort_sym) { |
| 1058 | sort__has_sym = 1; | 1066 | sort__has_sym = 1; |
| 1067 | } else if (sd->entry == &sort_dso) { | ||
| 1068 | sort__has_dso = 1; | ||
| 1059 | } | 1069 | } |
| 1060 | 1070 | ||
| 1061 | __sort_dimension__add(sd, i); | 1071 | __sort_dimension__add(sd, i); |
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 58b2bd8f38c9..7e67879ebd25 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c | |||
| @@ -129,7 +129,7 @@ static struct a2l_data *addr2line_init(const char *path) | |||
| 129 | 129 | ||
| 130 | out: | 130 | out: |
| 131 | if (a2l) { | 131 | if (a2l) { |
| 132 | free((void *)a2l->input); | 132 | zfree((void **)&a2l->input); |
| 133 | free(a2l); | 133 | free(a2l); |
| 134 | } | 134 | } |
| 135 | bfd_close(abfd); | 135 | bfd_close(abfd); |
| @@ -140,8 +140,8 @@ static void addr2line_cleanup(struct a2l_data *a2l) | |||
| 140 | { | 140 | { |
| 141 | if (a2l->abfd) | 141 | if (a2l->abfd) |
| 142 | bfd_close(a2l->abfd); | 142 | bfd_close(a2l->abfd); |
| 143 | free((void *)a2l->input); | 143 | zfree((void **)&a2l->input); |
| 144 | free(a2l->syms); | 144 | zfree(&a2l->syms); |
| 145 | free(a2l); | 145 | free(a2l); |
| 146 | } | 146 | } |
| 147 | 147 | ||
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index cfa906882e2c..4abe23550c73 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c | |||
| @@ -28,7 +28,7 @@ void strbuf_init(struct strbuf *sb, ssize_t hint) | |||
| 28 | void strbuf_release(struct strbuf *sb) | 28 | void strbuf_release(struct strbuf *sb) |
| 29 | { | 29 | { |
| 30 | if (sb->alloc) { | 30 | if (sb->alloc) { |
| 31 | free(sb->buf); | 31 | zfree(&sb->buf); |
| 32 | strbuf_init(sb, 0); | 32 | strbuf_init(sb, 0); |
| 33 | } | 33 | } |
| 34 | } | 34 | } |
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c index 3edd0538161f..79a757a2a15c 100644 --- a/tools/perf/util/strfilter.c +++ b/tools/perf/util/strfilter.c | |||
| @@ -14,7 +14,7 @@ static void strfilter_node__delete(struct strfilter_node *node) | |||
| 14 | { | 14 | { |
| 15 | if (node) { | 15 | if (node) { |
| 16 | if (node->p && !is_operator(*node->p)) | 16 | if (node->p && !is_operator(*node->p)) |
| 17 | free((char *)node->p); | 17 | zfree((char **)&node->p); |
| 18 | strfilter_node__delete(node->l); | 18 | strfilter_node__delete(node->l); |
| 19 | strfilter_node__delete(node->r); | 19 | strfilter_node__delete(node->r); |
| 20 | free(node); | 20 | free(node); |
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index f0b0c008c507..2553e5b55b89 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
| @@ -128,7 +128,7 @@ void argv_free(char **argv) | |||
| 128 | { | 128 | { |
| 129 | char **p; | 129 | char **p; |
| 130 | for (p = argv; *p; p++) | 130 | for (p = argv; *p; p++) |
| 131 | free(*p); | 131 | zfree(p); |
| 132 | 132 | ||
| 133 | free(argv); | 133 | free(argv); |
| 134 | } | 134 | } |
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index eabdce0a2daa..61a90bf24b4d 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include "strlist.h" | 7 | #include "strlist.h" |
| 8 | #include "util.h" | ||
| 8 | #include <errno.h> | 9 | #include <errno.h> |
| 9 | #include <stdio.h> | 10 | #include <stdio.h> |
| 10 | #include <stdlib.h> | 11 | #include <stdlib.h> |
| @@ -38,7 +39,7 @@ out_delete: | |||
| 38 | static void str_node__delete(struct str_node *snode, bool dupstr) | 39 | static void str_node__delete(struct str_node *snode, bool dupstr) |
| 39 | { | 40 | { |
| 40 | if (dupstr) | 41 | if (dupstr) |
| 41 | free((void *)snode->s); | 42 | zfree((void **)&snode->s); |
| 42 | free(snode); | 43 | free(snode); |
| 43 | } | 44 | } |
| 44 | 45 | ||
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 56a84f2cc46d..43262b83c541 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include "perf.h" | 22 | #include "perf.h" |
| 23 | #include "svghelper.h" | 23 | #include "svghelper.h" |
| 24 | #include "util.h" | ||
| 24 | #include "cpumap.h" | 25 | #include "cpumap.h" |
| 25 | 26 | ||
| 26 | static u64 first_time, last_time; | 27 | static u64 first_time, last_time; |
| @@ -708,8 +709,8 @@ int svg_build_topology_map(char *sib_core, int sib_core_nr, | |||
| 708 | return 0; | 709 | return 0; |
| 709 | 710 | ||
| 710 | exit: | 711 | exit: |
| 711 | free(t.sib_core); | 712 | zfree(&t.sib_core); |
| 712 | free(t.sib_thr); | 713 | zfree(&t.sib_thr); |
| 713 | 714 | ||
| 714 | return -1; | 715 | return -1; |
| 715 | } | 716 | } |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index bf0ce29567b6..4b0a127a4d3b 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
| @@ -554,7 +554,7 @@ bool symsrc__has_symtab(struct symsrc *ss) | |||
| 554 | 554 | ||
| 555 | void symsrc__destroy(struct symsrc *ss) | 555 | void symsrc__destroy(struct symsrc *ss) |
| 556 | { | 556 | { |
| 557 | free(ss->name); | 557 | zfree(&ss->name); |
| 558 | elf_end(ss->elf); | 558 | elf_end(ss->elf); |
| 559 | close(ss->fd); | 559 | close(ss->fd); |
| 560 | } | 560 | } |
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index ac7070a2f2b6..bd15f490d04f 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #include "symbol.h" | 1 | #include "symbol.h" |
| 2 | #include "util.h" | ||
| 2 | 3 | ||
| 3 | #include <stdio.h> | 4 | #include <stdio.h> |
| 4 | #include <fcntl.h> | 5 | #include <fcntl.h> |
| @@ -275,7 +276,7 @@ bool symsrc__has_symtab(struct symsrc *ss __maybe_unused) | |||
| 275 | 276 | ||
| 276 | void symsrc__destroy(struct symsrc *ss) | 277 | void symsrc__destroy(struct symsrc *ss) |
| 277 | { | 278 | { |
| 278 | free(ss->name); | 279 | zfree(&ss->name); |
| 279 | close(ss->fd); | 280 | close(ss->fd); |
| 280 | } | 281 | } |
| 281 | 282 | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 923d00040bbf..39ce9adbaaf0 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -796,7 +796,7 @@ static void delete_modules(struct rb_root *modules) | |||
| 796 | mi = rb_entry(next, struct module_info, rb_node); | 796 | mi = rb_entry(next, struct module_info, rb_node); |
| 797 | next = rb_next(&mi->rb_node); | 797 | next = rb_next(&mi->rb_node); |
| 798 | rb_erase(&mi->rb_node, modules); | 798 | rb_erase(&mi->rb_node, modules); |
| 799 | free(mi->name); | 799 | zfree(&mi->name); |
| 800 | free(mi); | 800 | free(mi); |
| 801 | } | 801 | } |
| 802 | } | 802 | } |
| @@ -1621,13 +1621,10 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, | |||
| 1621 | 1621 | ||
| 1622 | static void vmlinux_path__exit(void) | 1622 | static void vmlinux_path__exit(void) |
| 1623 | { | 1623 | { |
| 1624 | while (--vmlinux_path__nr_entries >= 0) { | 1624 | while (--vmlinux_path__nr_entries >= 0) |
| 1625 | free(vmlinux_path[vmlinux_path__nr_entries]); | 1625 | zfree(&vmlinux_path[vmlinux_path__nr_entries]); |
| 1626 | vmlinux_path[vmlinux_path__nr_entries] = NULL; | ||
| 1627 | } | ||
| 1628 | 1626 | ||
| 1629 | free(vmlinux_path); | 1627 | zfree(&vmlinux_path); |
| 1630 | vmlinux_path = NULL; | ||
| 1631 | } | 1628 | } |
| 1632 | 1629 | ||
| 1633 | static int vmlinux_path__init(void) | 1630 | static int vmlinux_path__init(void) |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 8a9d910c5345..cbd680361806 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -164,6 +164,7 @@ struct mem_info { | |||
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | struct addr_location { | 166 | struct addr_location { |
| 167 | struct machine *machine; | ||
| 167 | struct thread *thread; | 168 | struct thread *thread; |
| 168 | struct map *map; | 169 | struct map *map; |
| 169 | struct symbol *sym; | 170 | struct symbol *sym; |
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 9b5f856cc280..5d3215912105 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "strlist.h" | 9 | #include "strlist.h" |
| 10 | #include <string.h> | 10 | #include <string.h> |
| 11 | #include "thread_map.h" | 11 | #include "thread_map.h" |
| 12 | #include "util.h" | ||
| 12 | 13 | ||
| 13 | /* Skip "." and ".." directories */ | 14 | /* Skip "." and ".." directories */ |
| 14 | static int filter(const struct dirent *dir) | 15 | static int filter(const struct dirent *dir) |
| @@ -40,7 +41,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid) | |||
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | for (i=0; i<items; i++) | 43 | for (i=0; i<items; i++) |
| 43 | free(namelist[i]); | 44 | zfree(&namelist[i]); |
| 44 | free(namelist); | 45 | free(namelist); |
| 45 | 46 | ||
| 46 | return threads; | 47 | return threads; |
| @@ -117,7 +118,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) | |||
| 117 | threads->map[threads->nr + i] = atoi(namelist[i]->d_name); | 118 | threads->map[threads->nr + i] = atoi(namelist[i]->d_name); |
| 118 | 119 | ||
| 119 | for (i = 0; i < items; i++) | 120 | for (i = 0; i < items; i++) |
| 120 | free(namelist[i]); | 121 | zfree(&namelist[i]); |
| 121 | free(namelist); | 122 | free(namelist); |
| 122 | 123 | ||
| 123 | threads->nr += items; | 124 | threads->nr += items; |
| @@ -134,12 +135,11 @@ out_free_threads: | |||
| 134 | 135 | ||
| 135 | out_free_namelist: | 136 | out_free_namelist: |
| 136 | for (i = 0; i < items; i++) | 137 | for (i = 0; i < items; i++) |
| 137 | free(namelist[i]); | 138 | zfree(&namelist[i]); |
| 138 | free(namelist); | 139 | free(namelist); |
| 139 | 140 | ||
| 140 | out_free_closedir: | 141 | out_free_closedir: |
| 141 | free(threads); | 142 | zfree(&threads); |
| 142 | threads = NULL; | ||
| 143 | goto out_closedir; | 143 | goto out_closedir; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| @@ -194,7 +194,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) | |||
| 194 | 194 | ||
| 195 | for (i = 0; i < items; i++) { | 195 | for (i = 0; i < items; i++) { |
| 196 | threads->map[j++] = atoi(namelist[i]->d_name); | 196 | threads->map[j++] = atoi(namelist[i]->d_name); |
| 197 | free(namelist[i]); | 197 | zfree(&namelist[i]); |
| 198 | } | 198 | } |
| 199 | threads->nr = total_tasks; | 199 | threads->nr = total_tasks; |
| 200 | free(namelist); | 200 | free(namelist); |
| @@ -206,12 +206,11 @@ out: | |||
| 206 | 206 | ||
| 207 | out_free_namelist: | 207 | out_free_namelist: |
| 208 | for (i = 0; i < items; i++) | 208 | for (i = 0; i < items; i++) |
| 209 | free(namelist[i]); | 209 | zfree(&namelist[i]); |
| 210 | free(namelist); | 210 | free(namelist); |
| 211 | 211 | ||
| 212 | out_free_threads: | 212 | out_free_threads: |
| 213 | free(threads); | 213 | zfree(&threads); |
| 214 | threads = NULL; | ||
| 215 | goto out; | 214 | goto out; |
| 216 | } | 215 | } |
| 217 | 216 | ||
| @@ -262,8 +261,7 @@ out: | |||
| 262 | return threads; | 261 | return threads; |
| 263 | 262 | ||
| 264 | out_free_threads: | 263 | out_free_threads: |
| 265 | free(threads); | 264 | zfree(&threads); |
| 266 | threads = NULL; | ||
| 267 | goto out; | 265 | goto out; |
| 268 | } | 266 | } |
| 269 | 267 | ||
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index ce793c7dd23c..8e517def925b 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c | |||
| @@ -26,7 +26,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | |||
| 26 | float samples_per_sec; | 26 | float samples_per_sec; |
| 27 | float ksamples_per_sec; | 27 | float ksamples_per_sec; |
| 28 | float esamples_percent; | 28 | float esamples_percent; |
| 29 | struct perf_record_opts *opts = &top->record_opts; | 29 | struct record_opts *opts = &top->record_opts; |
| 30 | struct target *target = &opts->target; | 30 | struct target *target = &opts->target; |
| 31 | size_t ret = 0; | 31 | size_t ret = 0; |
| 32 | 32 | ||
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 88cfeaff600b..dab14d0ad3d0 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
| @@ -14,7 +14,7 @@ struct perf_session; | |||
| 14 | struct perf_top { | 14 | struct perf_top { |
| 15 | struct perf_tool tool; | 15 | struct perf_tool tool; |
| 16 | struct perf_evlist *evlist; | 16 | struct perf_evlist *evlist; |
| 17 | struct perf_record_opts record_opts; | 17 | struct record_opts record_opts; |
| 18 | /* | 18 | /* |
| 19 | * Symbols will be added here in perf_event__process_sample and will | 19 | * Symbols will be added here in perf_event__process_sample and will |
| 20 | * get out after decayed. | 20 | * get out after decayed. |
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index c354b95a2348..7e6fcfe8b438 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
| @@ -397,8 +397,8 @@ put_tracepoints_path(struct tracepoint_path *tps) | |||
| 397 | struct tracepoint_path *t = tps; | 397 | struct tracepoint_path *t = tps; |
| 398 | 398 | ||
| 399 | tps = tps->next; | 399 | tps = tps->next; |
| 400 | free(t->name); | 400 | zfree(&t->name); |
| 401 | free(t->system); | 401 | zfree(&t->system); |
| 402 | free(t); | 402 | free(t); |
| 403 | } | 403 | } |
| 404 | } | 404 | } |
| @@ -562,10 +562,8 @@ out: | |||
| 562 | output_fd = fd; | 562 | output_fd = fd; |
| 563 | } | 563 | } |
| 564 | 564 | ||
| 565 | if (err) { | 565 | if (err) |
| 566 | free(tdata); | 566 | zfree(&tdata); |
| 567 | tdata = NULL; | ||
| 568 | } | ||
| 569 | 567 | ||
| 570 | put_tracepoints_path(tps); | 568 | put_tracepoints_path(tps); |
| 571 | return tdata; | 569 | return tdata; |
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 95199e4eea97..57aaccc1692e 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
| @@ -38,9 +38,8 @@ static int stop_script_unsupported(void) | |||
| 38 | static void process_event_unsupported(union perf_event *event __maybe_unused, | 38 | static void process_event_unsupported(union perf_event *event __maybe_unused, |
| 39 | struct perf_sample *sample __maybe_unused, | 39 | struct perf_sample *sample __maybe_unused, |
| 40 | struct perf_evsel *evsel __maybe_unused, | 40 | struct perf_evsel *evsel __maybe_unused, |
| 41 | struct machine *machine __maybe_unused, | ||
| 42 | struct thread *thread __maybe_unused, | 41 | struct thread *thread __maybe_unused, |
| 43 | struct addr_location *al __maybe_unused) | 42 | struct addr_location *al __maybe_unused) |
| 44 | { | 43 | { |
| 45 | } | 44 | } |
| 46 | 45 | ||
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 3a01618c5b87..7b6d68688327 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
| @@ -68,7 +68,6 @@ struct scripting_ops { | |||
| 68 | void (*process_event) (union perf_event *event, | 68 | void (*process_event) (union perf_event *event, |
| 69 | struct perf_sample *sample, | 69 | struct perf_sample *sample, |
| 70 | struct perf_evsel *evsel, | 70 | struct perf_evsel *evsel, |
| 71 | struct machine *machine, | ||
| 72 | struct thread *thread, | 71 | struct thread *thread, |
| 73 | struct addr_location *al); | 72 | struct addr_location *al); |
| 74 | int (*generate_script) (struct pevent *pevent, const char *outfile); | 73 | int (*generate_script) (struct pevent *pevent, const char *outfile); |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 9a2c268ad718..6995d66f225c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
| @@ -186,6 +186,8 @@ static inline void *zalloc(size_t size) | |||
| 186 | return calloc(1, size); | 186 | return calloc(1, size); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) | ||
| 190 | |||
| 189 | static inline int has_extension(const char *filename, const char *ext) | 191 | static inline int has_extension(const char *filename, const char *ext) |
| 190 | { | 192 | { |
| 191 | size_t len = strlen(filename); | 193 | size_t len = strlen(filename); |
diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 697c8b4e59cc..0fb3c1fcd3e6 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c | |||
| @@ -31,14 +31,14 @@ void perf_read_values_destroy(struct perf_read_values *values) | |||
| 31 | return; | 31 | return; |
| 32 | 32 | ||
| 33 | for (i = 0; i < values->threads; i++) | 33 | for (i = 0; i < values->threads; i++) |
| 34 | free(values->value[i]); | 34 | zfree(&values->value[i]); |
| 35 | free(values->value); | 35 | zfree(&values->value); |
| 36 | free(values->pid); | 36 | zfree(&values->pid); |
| 37 | free(values->tid); | 37 | zfree(&values->tid); |
| 38 | free(values->counterrawid); | 38 | zfree(&values->counterrawid); |
| 39 | for (i = 0; i < values->counters; i++) | 39 | for (i = 0; i < values->counters; i++) |
| 40 | free(values->countername[i]); | 40 | zfree(&values->countername[i]); |
| 41 | free(values->countername); | 41 | zfree(&values->countername); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | static void perf_read_values__enlarge_threads(struct perf_read_values *values) | 44 | static void perf_read_values__enlarge_threads(struct perf_read_values *values) |
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index ee76544deecb..8abbef164b4e 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include | |||
| @@ -61,6 +61,7 @@ QUIET_SUBDIR1 = | |||
| 61 | ifneq ($(findstring $(MAKEFLAGS),s),s) | 61 | ifneq ($(findstring $(MAKEFLAGS),s),s) |
| 62 | ifneq ($(V),1) | 62 | ifneq ($(V),1) |
| 63 | QUIET_CC = @echo ' CC '$@; | 63 | QUIET_CC = @echo ' CC '$@; |
| 64 | QUIET_CC_FPIC = @echo ' CC FPIC '$@; | ||
| 64 | QUIET_AR = @echo ' AR '$@; | 65 | QUIET_AR = @echo ' AR '$@; |
| 65 | QUIET_LINK = @echo ' LINK '$@; | 66 | QUIET_LINK = @echo ' LINK '$@; |
| 66 | QUIET_MKDIR = @echo ' MKDIR '$@; | 67 | QUIET_MKDIR = @echo ' MKDIR '$@; |
| @@ -76,5 +77,8 @@ ifneq ($(findstring $(MAKEFLAGS),s),s) | |||
| 76 | +@echo ' DESCEND '$(1); \ | 77 | +@echo ' DESCEND '$(1); \ |
| 77 | mkdir -p $(OUTPUT)$(1) && \ | 78 | mkdir -p $(OUTPUT)$(1) && \ |
| 78 | $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) | 79 | $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) |
| 80 | |||
| 81 | QUIET_CLEAN = @printf ' CLEAN %s\n' $1; | ||
| 82 | QUIET_INSTALL = @printf ' INSTALL %s\n' $1; | ||
| 79 | endif | 83 | endif |
| 80 | endif | 84 | endif |
