Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf updates from Arnaldo Carvalho de Melo:

User visible changes:

Improvements:

* Support showing source code, asking for variables to be collected
at probe time and other 'perf probe' operations that use DWARF information.

This supports only binaries with debugging information at this time, detached
debuginfo (aka debuginfo packages) support should come in later patches.
(Masami Hiramatsu)

* Add a perf.data file header window in the 'perf report' TUI, associated
with the 'i' hotkey, providing a counterpart to the --header option in the
stdio UI. (Namhyung Kim)

* Guest related improvements to 'perf kvm', including allowing to
specify a directory with guest specific /proc information. (Dongsheng Yang)

* Print session information only if --stdio is given (Namhyung Kim)

Developer stuff:

Fixes:

* Get rid of a duplicate va_end() in error reporting (Namhyung Kim)

* If a hist entry doesn't have symbol information, compare it with its
address. Affects upcoming new feature (--cumulate) (Namhyung Kim)

Improvements:

* Make libtraceevent install target quieter (Jiri Olsa)

* Make tests/make output more compact (Jiri Olsa)

* Ignore generated files in feature-checks (Chunwei Chen)

New APIs:

* Introduce pevent_filter_strerror() in libtraceevent, similar in
purpose to libc's strerror() function. (Namhyung Kim)

Refactorings:

* Use perf_data_file methods to write output file in 'record' and
'inject' (Jiri Olsa)

* Use pr_*() functions where applicable in 'report' (Namhyumg Kim)

* Add 'machine' 'addr_location' struct to have full picture (machine,
thread, map, symbol, addr) for a (partially) resolved address, reducing
function signatures (Arnaldo Carvalho de Melo)

* Reduce code duplication in the histogram entry creation/insertion. (Arnaldo Carvalho de Melo)

* Auto allocate annotation histogram data structures, (Arnaldo Carvalho de Melo)

* No need to test against NULL before calling free, also set
freed memory in struct pointers to NULL, to help fixing use after
free bugs. (Arnaldo Carvalho de Melo>

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

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