aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-09-07 01:36:59 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-07 01:36:59 -0400
commit479d875835a49e849683743ec50c30b6a429696b (patch)
tree616b96197e489d3fbd5ef8bdde5a59a50d6dcd76
parentbab57e994d6311298b4e3915d2c75296cd81638c (diff)
parent275ef3878f698941353780440fec6926107a320b (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: - Rename libtraceevent 'private' struct member to 'priv' so that it works in C++, from Steven Rostedt - Remove lots of exit()/die() calls from tools so that the main perf exit routine can take place, from David Ahern - Fix x86 build on x86-64, from David Ahern. - Remove some headers that prevented perf from building on Android, from David Ahern - {int,str,rb}list fixes from Suzuki K Poulose - perf.data header fixes from Namhyung Kim - Replace needless mempcpy with memcpy, to allow build on Android, from Irina Tirdea - Allow user to indicate objdump path, needed in cross environments, from Maciek Borzecki - Fix hardware cache event name generation, fix from Jiri Olsa - Add round trip test for sw, hw and cache event names, catching the problem Jiri fixed, after Jiri's patch, the test passes successfully. - Clean target should do clean for lib/traceevent too, fix from David Ahern - Check the right variable for allocation failure, fix from Namhyung Kim - Set up evsel->tp_format regardless of evsel->name being set already, fix from Namhyung Kim Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/lib/traceevent/event-parse.h4
-rw-r--r--tools/perf/Documentation/perf-annotate.txt3
-rw-r--r--tools/perf/Documentation/perf-report.txt3
-rw-r--r--tools/perf/Makefile9
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-help.c48
-rw-r--r--tools/perf/builtin-lock.c181
-rw-r--r--tools/perf/builtin-record.c158
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-script.c60
-rw-r--r--tools/perf/builtin-stat.c7
-rw-r--r--tools/perf/builtin-test.c114
-rw-r--r--tools/perf/util/annotate.c4
-rw-r--r--tools/perf/util/annotate.h1
-rw-r--r--tools/perf/util/event.c35
-rw-r--r--tools/perf/util/evlist.c13
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/evsel.c6
-rw-r--r--tools/perf/util/evsel.h6
-rw-r--r--tools/perf/util/header.c45
-rw-r--r--tools/perf/util/intlist.c4
-rw-r--r--tools/perf/util/parse-events.c2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c8
-rw-r--r--tools/perf/util/session.c24
-rw-r--r--tools/perf/util/strlist.c2
-rw-r--r--tools/perf/util/target.c4
-rw-r--r--tools/perf/util/util.h5
27 files changed, 550 insertions, 202 deletions
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 527df038a25..863a0bbda7f 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -49,7 +49,7 @@ struct pevent_record {
49 int cpu; 49 int cpu;
50 int ref_count; 50 int ref_count;
51 int locked; /* Do not free, even if ref_count is zero */ 51 int locked; /* Do not free, even if ref_count is zero */
52 void *private; 52 void *priv;
53#if DEBUG_RECORD 53#if DEBUG_RECORD
54 struct pevent_record *prev; 54 struct pevent_record *prev;
55 struct pevent_record *next; 55 struct pevent_record *next;
@@ -106,7 +106,7 @@ struct plugin_option {
106 char *plugin_alias; 106 char *plugin_alias;
107 char *description; 107 char *description;
108 char *value; 108 char *value;
109 void *private; 109 void *priv;
110 int set; 110 int set;
111}; 111};
112 112
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index c89f9e1453f..c8ffd9fd5c6 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -85,6 +85,9 @@ OPTIONS
85-M:: 85-M::
86--disassembler-style=:: Set disassembler style for objdump. 86--disassembler-style=:: Set disassembler style for objdump.
87 87
88--objdump=<path>::
89 Path to objdump binary.
90
88SEE ALSO 91SEE ALSO
89-------- 92--------
90linkperf:perf-record[1], linkperf:perf-report[1] 93linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 495210a612c..f4d91bebd59 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -168,6 +168,9 @@ OPTIONS
168 branch stacks and it will automatically switch to the branch view mode, 168 branch stacks and it will automatically switch to the branch view mode,
169 unless --no-branch-stack is used. 169 unless --no-branch-stack is used.
170 170
171--objdump=<path>::
172 Path to objdump binary.
173
171SEE ALSO 174SEE ALSO
172-------- 175--------
173linkperf:perf-stat[1], linkperf:perf-annotate[1] 176linkperf:perf-stat[1], linkperf:perf-annotate[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 722ddee61f9..afd50757490 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -64,12 +64,12 @@ AR = $(CROSS_COMPILE)ar
64 64
65# Additional ARCH settings for x86 65# Additional ARCH settings for x86
66ifeq ($(ARCH),i386) 66ifeq ($(ARCH),i386)
67 ARCH := x86 67 override ARCH := x86
68 NO_PERF_REGS := 0 68 NO_PERF_REGS := 0
69 LIBUNWIND_LIBS = -lunwind -lunwind-x86 69 LIBUNWIND_LIBS = -lunwind -lunwind-x86
70endif 70endif
71ifeq ($(ARCH),x86_64) 71ifeq ($(ARCH),x86_64)
72 ARCH := x86 72 override ARCH := x86
73 IS_X86_64 := 0 73 IS_X86_64 := 0
74 ifeq (, $(findstring m32,$(EXTRA_CFLAGS))) 74 ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
75 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) 75 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
@@ -917,6 +917,9 @@ $(LIB_FILE): $(LIB_OBJS)
917$(LIBTRACEEVENT): 917$(LIBTRACEEVENT):
918 $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a 918 $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a
919 919
920$(LIBTRACEEVENT)-clean:
921 $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
922
920help: 923help:
921 @echo 'Perf make targets:' 924 @echo 'Perf make targets:'
922 @echo ' doc - make *all* documentation (see below)' 925 @echo ' doc - make *all* documentation (see below)'
@@ -1056,7 +1059,7 @@ quick-install-html:
1056 1059
1057### Cleaning rules 1060### Cleaning rules
1058 1061
1059clean: 1062clean: $(LIBTRACEEVENT)-clean
1060 $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) 1063 $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
1061 $(RM) $(ALL_PROGRAMS) perf 1064 $(RM) $(ALL_PROGRAMS) perf
1062 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* 1065 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 67522cf8740..2f3f0029c0f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -282,6 +282,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
282 "Display raw encoding of assembly instructions (default)"), 282 "Display raw encoding of assembly instructions (default)"),
283 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", 283 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
284 "Specify disassembler style (e.g. -M intel for intel syntax)"), 284 "Specify disassembler style (e.g. -M intel for intel syntax)"),
285 OPT_STRING(0, "objdump", &objdump_path, "path",
286 "objdump binary to use for disassembly and annotations"),
285 OPT_END() 287 OPT_END()
286 }; 288 };
287 289
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 6d5a8a7faf4..f9daae5ac47 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -24,13 +24,14 @@ static struct man_viewer_info_list {
24} *man_viewer_info_list; 24} *man_viewer_info_list;
25 25
26enum help_format { 26enum help_format {
27 HELP_FORMAT_NONE,
27 HELP_FORMAT_MAN, 28 HELP_FORMAT_MAN,
28 HELP_FORMAT_INFO, 29 HELP_FORMAT_INFO,
29 HELP_FORMAT_WEB, 30 HELP_FORMAT_WEB,
30}; 31};
31 32
32static bool show_all = false; 33static bool show_all = false;
33static enum help_format help_format = HELP_FORMAT_MAN; 34static enum help_format help_format = HELP_FORMAT_NONE;
34static struct option builtin_help_options[] = { 35static struct option builtin_help_options[] = {
35 OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), 36 OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
36 OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), 37 OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
@@ -54,7 +55,9 @@ static enum help_format parse_help_format(const char *format)
54 return HELP_FORMAT_INFO; 55 return HELP_FORMAT_INFO;
55 if (!strcmp(format, "web") || !strcmp(format, "html")) 56 if (!strcmp(format, "web") || !strcmp(format, "html"))
56 return HELP_FORMAT_WEB; 57 return HELP_FORMAT_WEB;
57 die("unrecognized help format '%s'", format); 58
59 pr_err("unrecognized help format '%s'", format);
60 return HELP_FORMAT_NONE;
58} 61}
59 62
60static const char *get_man_viewer_info(const char *name) 63static const char *get_man_viewer_info(const char *name)
@@ -259,6 +262,8 @@ static int perf_help_config(const char *var, const char *value, void *cb)
259 if (!value) 262 if (!value)
260 return config_error_nonbool(var); 263 return config_error_nonbool(var);
261 help_format = parse_help_format(value); 264 help_format = parse_help_format(value);
265 if (help_format == HELP_FORMAT_NONE)
266 return -1;
262 return 0; 267 return 0;
263 } 268 }
264 if (!strcmp(var, "man.viewer")) { 269 if (!strcmp(var, "man.viewer")) {
@@ -352,7 +357,7 @@ static void exec_viewer(const char *name, const char *page)
352 warning("'%s': unknown man viewer.", name); 357 warning("'%s': unknown man viewer.", name);
353} 358}
354 359
355static void show_man_page(const char *perf_cmd) 360static int show_man_page(const char *perf_cmd)
356{ 361{
357 struct man_viewer_list *viewer; 362 struct man_viewer_list *viewer;
358 const char *page = cmd_to_page(perf_cmd); 363 const char *page = cmd_to_page(perf_cmd);
@@ -365,28 +370,35 @@ static void show_man_page(const char *perf_cmd)
365 if (fallback) 370 if (fallback)
366 exec_viewer(fallback, page); 371 exec_viewer(fallback, page);
367 exec_viewer("man", page); 372 exec_viewer("man", page);
368 die("no man viewer handled the request"); 373
374 pr_err("no man viewer handled the request");
375 return -1;
369} 376}
370 377
371static void show_info_page(const char *perf_cmd) 378static int show_info_page(const char *perf_cmd)
372{ 379{
373 const char *page = cmd_to_page(perf_cmd); 380 const char *page = cmd_to_page(perf_cmd);
374 setenv("INFOPATH", system_path(PERF_INFO_PATH), 1); 381 setenv("INFOPATH", system_path(PERF_INFO_PATH), 1);
375 execlp("info", "info", "perfman", page, NULL); 382 execlp("info", "info", "perfman", page, NULL);
383 return -1;
376} 384}
377 385
378static void get_html_page_path(struct strbuf *page_path, const char *page) 386static int get_html_page_path(struct strbuf *page_path, const char *page)
379{ 387{
380 struct stat st; 388 struct stat st;
381 const char *html_path = system_path(PERF_HTML_PATH); 389 const char *html_path = system_path(PERF_HTML_PATH);
382 390
383 /* Check that we have a perf documentation directory. */ 391 /* Check that we have a perf documentation directory. */
384 if (stat(mkpath("%s/perf.html", html_path), &st) 392 if (stat(mkpath("%s/perf.html", html_path), &st)
385 || !S_ISREG(st.st_mode)) 393 || !S_ISREG(st.st_mode)) {
386 die("'%s': not a documentation directory.", html_path); 394 pr_err("'%s': not a documentation directory.", html_path);
395 return -1;
396 }
387 397
388 strbuf_init(page_path, 0); 398 strbuf_init(page_path, 0);
389 strbuf_addf(page_path, "%s/%s.html", html_path, page); 399 strbuf_addf(page_path, "%s/%s.html", html_path, page);
400
401 return 0;
390} 402}
391 403
392/* 404/*
@@ -401,19 +413,23 @@ static void open_html(const char *path)
401} 413}
402#endif 414#endif
403 415
404static void show_html_page(const char *perf_cmd) 416static int show_html_page(const char *perf_cmd)
405{ 417{
406 const char *page = cmd_to_page(perf_cmd); 418 const char *page = cmd_to_page(perf_cmd);
407 struct strbuf page_path; /* it leaks but we exec bellow */ 419 struct strbuf page_path; /* it leaks but we exec bellow */
408 420
409 get_html_page_path(&page_path, page); 421 if (get_html_page_path(&page_path, page) != 0)
422 return -1;
410 423
411 open_html(page_path.buf); 424 open_html(page_path.buf);
425
426 return 0;
412} 427}
413 428
414int cmd_help(int argc, const char **argv, const char *prefix __used) 429int cmd_help(int argc, const char **argv, const char *prefix __used)
415{ 430{
416 const char *alias; 431 const char *alias;
432 int rc = 0;
417 433
418 load_command_list("perf-", &main_cmds, &other_cmds); 434 load_command_list("perf-", &main_cmds, &other_cmds);
419 435
@@ -444,16 +460,20 @@ int cmd_help(int argc, const char **argv, const char *prefix __used)
444 460
445 switch (help_format) { 461 switch (help_format) {
446 case HELP_FORMAT_MAN: 462 case HELP_FORMAT_MAN:
447 show_man_page(argv[0]); 463 rc = show_man_page(argv[0]);
448 break; 464 break;
449 case HELP_FORMAT_INFO: 465 case HELP_FORMAT_INFO:
450 show_info_page(argv[0]); 466 rc = show_info_page(argv[0]);
451 break; 467 break;
452 case HELP_FORMAT_WEB: 468 case HELP_FORMAT_WEB:
453 show_html_page(argv[0]); 469 rc = show_html_page(argv[0]);
470 break;
471 case HELP_FORMAT_NONE:
472 /* fall-through */
454 default: 473 default:
474 rc = -1;
455 break; 475 break;
456 } 476 }
457 477
458 return 0; 478 return rc;
459} 479}
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 585aae2858b..75153c87e65 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -161,8 +161,10 @@ static struct thread_stat *thread_stat_findnew_after_first(u32 tid)
161 return st; 161 return st;
162 162
163 st = zalloc(sizeof(struct thread_stat)); 163 st = zalloc(sizeof(struct thread_stat));
164 if (!st) 164 if (!st) {
165 die("memory allocation failed\n"); 165 pr_err("memory allocation failed\n");
166 return NULL;
167 }
166 168
167 st->tid = tid; 169 st->tid = tid;
168 INIT_LIST_HEAD(&st->seq_list); 170 INIT_LIST_HEAD(&st->seq_list);
@@ -181,8 +183,10 @@ static struct thread_stat *thread_stat_findnew_first(u32 tid)
181 struct thread_stat *st; 183 struct thread_stat *st;
182 184
183 st = zalloc(sizeof(struct thread_stat)); 185 st = zalloc(sizeof(struct thread_stat));
184 if (!st) 186 if (!st) {
185 die("memory allocation failed\n"); 187 pr_err("memory allocation failed\n");
188 return NULL;
189 }
186 st->tid = tid; 190 st->tid = tid;
187 INIT_LIST_HEAD(&st->seq_list); 191 INIT_LIST_HEAD(&st->seq_list);
188 192
@@ -248,18 +252,20 @@ struct lock_key keys[] = {
248 { NULL, NULL } 252 { NULL, NULL }
249}; 253};
250 254
251static void select_key(void) 255static int select_key(void)
252{ 256{
253 int i; 257 int i;
254 258
255 for (i = 0; keys[i].name; i++) { 259 for (i = 0; keys[i].name; i++) {
256 if (!strcmp(keys[i].name, sort_key)) { 260 if (!strcmp(keys[i].name, sort_key)) {
257 compare = keys[i].key; 261 compare = keys[i].key;
258 return; 262 return 0;
259 } 263 }
260 } 264 }
261 265
262 die("Unknown compare key:%s\n", sort_key); 266 pr_err("Unknown compare key: %s\n", sort_key);
267
268 return -1;
263} 269}
264 270
265static void insert_to_result(struct lock_stat *st, 271static void insert_to_result(struct lock_stat *st,
@@ -324,7 +330,8 @@ static struct lock_stat *lock_stat_findnew(void *addr, const char *name)
324 return new; 330 return new;
325 331
326alloc_failed: 332alloc_failed:
327 die("memory allocation failed\n"); 333 pr_err("memory allocation failed\n");
334 return NULL;
328} 335}
329 336
330static const char *input_name; 337static const char *input_name;
@@ -356,16 +363,16 @@ struct trace_release_event {
356}; 363};
357 364
358struct trace_lock_handler { 365struct trace_lock_handler {
359 void (*acquire_event)(struct trace_acquire_event *, 366 int (*acquire_event)(struct trace_acquire_event *,
360 const struct perf_sample *sample); 367 const struct perf_sample *sample);
361 368
362 void (*acquired_event)(struct trace_acquired_event *, 369 int (*acquired_event)(struct trace_acquired_event *,
363 const struct perf_sample *sample); 370 const struct perf_sample *sample);
364 371
365 void (*contended_event)(struct trace_contended_event *, 372 int (*contended_event)(struct trace_contended_event *,
366 const struct perf_sample *sample); 373 const struct perf_sample *sample);
367 374
368 void (*release_event)(struct trace_release_event *, 375 int (*release_event)(struct trace_release_event *,
369 const struct perf_sample *sample); 376 const struct perf_sample *sample);
370}; 377};
371 378
@@ -379,8 +386,10 @@ static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr)
379 } 386 }
380 387
381 seq = zalloc(sizeof(struct lock_seq_stat)); 388 seq = zalloc(sizeof(struct lock_seq_stat));
382 if (!seq) 389 if (!seq) {
383 die("Not enough memory\n"); 390 pr_err("memory allocation failed\n");
391 return NULL;
392 }
384 seq->state = SEQ_STATE_UNINITIALIZED; 393 seq->state = SEQ_STATE_UNINITIALIZED;
385 seq->addr = addr; 394 seq->addr = addr;
386 395
@@ -403,7 +412,7 @@ enum acquire_flags {
403 READ_LOCK = 2, 412 READ_LOCK = 2,
404}; 413};
405 414
406static void 415static int
407report_lock_acquire_event(struct trace_acquire_event *acquire_event, 416report_lock_acquire_event(struct trace_acquire_event *acquire_event,
408 const struct perf_sample *sample) 417 const struct perf_sample *sample)
409{ 418{
@@ -412,11 +421,18 @@ report_lock_acquire_event(struct trace_acquire_event *acquire_event,
412 struct lock_seq_stat *seq; 421 struct lock_seq_stat *seq;
413 422
414 ls = lock_stat_findnew(acquire_event->addr, acquire_event->name); 423 ls = lock_stat_findnew(acquire_event->addr, acquire_event->name);
424 if (!ls)
425 return -1;
415 if (ls->discard) 426 if (ls->discard)
416 return; 427 return 0;
417 428
418 ts = thread_stat_findnew(sample->tid); 429 ts = thread_stat_findnew(sample->tid);
430 if (!ts)
431 return -1;
432
419 seq = get_seq(ts, acquire_event->addr); 433 seq = get_seq(ts, acquire_event->addr);
434 if (!seq)
435 return -1;
420 436
421 switch (seq->state) { 437 switch (seq->state) {
422 case SEQ_STATE_UNINITIALIZED: 438 case SEQ_STATE_UNINITIALIZED:
@@ -461,10 +477,10 @@ broken:
461 ls->nr_acquire++; 477 ls->nr_acquire++;
462 seq->prev_event_time = sample->time; 478 seq->prev_event_time = sample->time;
463end: 479end:
464 return; 480 return 0;
465} 481}
466 482
467static void 483static int
468report_lock_acquired_event(struct trace_acquired_event *acquired_event, 484report_lock_acquired_event(struct trace_acquired_event *acquired_event,
469 const struct perf_sample *sample) 485 const struct perf_sample *sample)
470{ 486{
@@ -475,16 +491,23 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event,
475 u64 contended_term; 491 u64 contended_term;
476 492
477 ls = lock_stat_findnew(acquired_event->addr, acquired_event->name); 493 ls = lock_stat_findnew(acquired_event->addr, acquired_event->name);
494 if (!ls)
495 return -1;
478 if (ls->discard) 496 if (ls->discard)
479 return; 497 return 0;
480 498
481 ts = thread_stat_findnew(sample->tid); 499 ts = thread_stat_findnew(sample->tid);
500 if (!ts)
501 return -1;
502
482 seq = get_seq(ts, acquired_event->addr); 503 seq = get_seq(ts, acquired_event->addr);
504 if (!seq)
505 return -1;
483 506
484 switch (seq->state) { 507 switch (seq->state) {
485 case SEQ_STATE_UNINITIALIZED: 508 case SEQ_STATE_UNINITIALIZED:
486 /* orphan event, do nothing */ 509 /* orphan event, do nothing */
487 return; 510 return 0;
488 case SEQ_STATE_ACQUIRING: 511 case SEQ_STATE_ACQUIRING:
489 break; 512 break;
490 case SEQ_STATE_CONTENDED: 513 case SEQ_STATE_CONTENDED:
@@ -515,10 +538,10 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event,
515 ls->nr_acquired++; 538 ls->nr_acquired++;
516 seq->prev_event_time = timestamp; 539 seq->prev_event_time = timestamp;
517end: 540end:
518 return; 541 return 0;
519} 542}
520 543
521static void 544static int
522report_lock_contended_event(struct trace_contended_event *contended_event, 545report_lock_contended_event(struct trace_contended_event *contended_event,
523 const struct perf_sample *sample) 546 const struct perf_sample *sample)
524{ 547{
@@ -527,16 +550,23 @@ report_lock_contended_event(struct trace_contended_event *contended_event,
527 struct lock_seq_stat *seq; 550 struct lock_seq_stat *seq;
528 551
529 ls = lock_stat_findnew(contended_event->addr, contended_event->name); 552 ls = lock_stat_findnew(contended_event->addr, contended_event->name);
553 if (!ls)
554 return -1;
530 if (ls->discard) 555 if (ls->discard)
531 return; 556 return 0;
532 557
533 ts = thread_stat_findnew(sample->tid); 558 ts = thread_stat_findnew(sample->tid);
559 if (!ts)
560 return -1;
561
534 seq = get_seq(ts, contended_event->addr); 562 seq = get_seq(ts, contended_event->addr);
563 if (!seq)
564 return -1;
535 565
536 switch (seq->state) { 566 switch (seq->state) {
537 case SEQ_STATE_UNINITIALIZED: 567 case SEQ_STATE_UNINITIALIZED:
538 /* orphan event, do nothing */ 568 /* orphan event, do nothing */
539 return; 569 return 0;
540 case SEQ_STATE_ACQUIRING: 570 case SEQ_STATE_ACQUIRING:
541 break; 571 break;
542 case SEQ_STATE_RELEASED: 572 case SEQ_STATE_RELEASED:
@@ -559,10 +589,10 @@ report_lock_contended_event(struct trace_contended_event *contended_event,
559 ls->nr_contended++; 589 ls->nr_contended++;
560 seq->prev_event_time = sample->time; 590 seq->prev_event_time = sample->time;
561end: 591end:
562 return; 592 return 0;
563} 593}
564 594
565static void 595static int
566report_lock_release_event(struct trace_release_event *release_event, 596report_lock_release_event(struct trace_release_event *release_event,
567 const struct perf_sample *sample) 597 const struct perf_sample *sample)
568{ 598{
@@ -571,11 +601,18 @@ report_lock_release_event(struct trace_release_event *release_event,
571 struct lock_seq_stat *seq; 601 struct lock_seq_stat *seq;
572 602
573 ls = lock_stat_findnew(release_event->addr, release_event->name); 603 ls = lock_stat_findnew(release_event->addr, release_event->name);
604 if (!ls)
605 return -1;
574 if (ls->discard) 606 if (ls->discard)
575 return; 607 return 0;
576 608
577 ts = thread_stat_findnew(sample->tid); 609 ts = thread_stat_findnew(sample->tid);
610 if (!ts)
611 return -1;
612
578 seq = get_seq(ts, release_event->addr); 613 seq = get_seq(ts, release_event->addr);
614 if (!seq)
615 return -1;
579 616
580 switch (seq->state) { 617 switch (seq->state) {
581 case SEQ_STATE_UNINITIALIZED: 618 case SEQ_STATE_UNINITIALIZED:
@@ -609,7 +646,7 @@ free_seq:
609 list_del(&seq->list); 646 list_del(&seq->list);
610 free(seq); 647 free(seq);
611end: 648end:
612 return; 649 return 0;
613} 650}
614 651
615/* lock oriented handlers */ 652/* lock oriented handlers */
@@ -623,13 +660,14 @@ static struct trace_lock_handler report_lock_ops = {
623 660
624static struct trace_lock_handler *trace_handler; 661static struct trace_lock_handler *trace_handler;
625 662
626static void perf_evsel__process_lock_acquire(struct perf_evsel *evsel, 663static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel,
627 struct perf_sample *sample) 664 struct perf_sample *sample)
628{ 665{
629 struct trace_acquire_event acquire_event; 666 struct trace_acquire_event acquire_event;
630 struct event_format *event = evsel->tp_format; 667 struct event_format *event = evsel->tp_format;
631 void *data = sample->raw_data; 668 void *data = sample->raw_data;
632 u64 tmp; /* this is required for casting... */ 669 u64 tmp; /* this is required for casting... */
670 int rc = 0;
633 671
634 tmp = raw_field_value(event, "lockdep_addr", data); 672 tmp = raw_field_value(event, "lockdep_addr", data);
635 memcpy(&acquire_event.addr, &tmp, sizeof(void *)); 673 memcpy(&acquire_event.addr, &tmp, sizeof(void *));
@@ -637,70 +675,84 @@ static void perf_evsel__process_lock_acquire(struct perf_evsel *evsel,
637 acquire_event.flag = (int)raw_field_value(event, "flag", data); 675 acquire_event.flag = (int)raw_field_value(event, "flag", data);
638 676
639 if (trace_handler->acquire_event) 677 if (trace_handler->acquire_event)
640 trace_handler->acquire_event(&acquire_event, sample); 678 rc = trace_handler->acquire_event(&acquire_event, sample);
679
680 return rc;
641} 681}
642 682
643static void perf_evsel__process_lock_acquired(struct perf_evsel *evsel, 683static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel,
644 struct perf_sample *sample) 684 struct perf_sample *sample)
645{ 685{
646 struct trace_acquired_event acquired_event; 686 struct trace_acquired_event acquired_event;
647 struct event_format *event = evsel->tp_format; 687 struct event_format *event = evsel->tp_format;
648 void *data = sample->raw_data; 688 void *data = sample->raw_data;
649 u64 tmp; /* this is required for casting... */ 689 u64 tmp; /* this is required for casting... */
690 int rc = 0;
650 691
651 tmp = raw_field_value(event, "lockdep_addr", data); 692 tmp = raw_field_value(event, "lockdep_addr", data);
652 memcpy(&acquired_event.addr, &tmp, sizeof(void *)); 693 memcpy(&acquired_event.addr, &tmp, sizeof(void *));
653 acquired_event.name = (char *)raw_field_ptr(event, "name", data); 694 acquired_event.name = (char *)raw_field_ptr(event, "name", data);
654 695
655 if (trace_handler->acquire_event) 696 if (trace_handler->acquired_event)
656 trace_handler->acquired_event(&acquired_event, sample); 697 rc = trace_handler->acquired_event(&acquired_event, sample);
698
699 return rc;
657} 700}
658 701
659static void perf_evsel__process_lock_contended(struct perf_evsel *evsel, 702static int perf_evsel__process_lock_contended(struct perf_evsel *evsel,
660 struct perf_sample *sample) 703 struct perf_sample *sample)
661{ 704{
662 struct trace_contended_event contended_event; 705 struct trace_contended_event contended_event;
663 struct event_format *event = evsel->tp_format; 706 struct event_format *event = evsel->tp_format;
664 void *data = sample->raw_data; 707 void *data = sample->raw_data;
665 u64 tmp; /* this is required for casting... */ 708 u64 tmp; /* this is required for casting... */
709 int rc = 0;
666 710
667 tmp = raw_field_value(event, "lockdep_addr", data); 711 tmp = raw_field_value(event, "lockdep_addr", data);
668 memcpy(&contended_event.addr, &tmp, sizeof(void *)); 712 memcpy(&contended_event.addr, &tmp, sizeof(void *));
669 contended_event.name = (char *)raw_field_ptr(event, "name", data); 713 contended_event.name = (char *)raw_field_ptr(event, "name", data);
670 714
671 if (trace_handler->acquire_event) 715 if (trace_handler->contended_event)
672 trace_handler->contended_event(&contended_event, sample); 716 rc = trace_handler->contended_event(&contended_event, sample);
717
718 return rc;
673} 719}
674 720
675static void perf_evsel__process_lock_release(struct perf_evsel *evsel, 721static int perf_evsel__process_lock_release(struct perf_evsel *evsel,
676 struct perf_sample *sample) 722 struct perf_sample *sample)
677{ 723{
678 struct trace_release_event release_event; 724 struct trace_release_event release_event;
679 struct event_format *event = evsel->tp_format; 725 struct event_format *event = evsel->tp_format;
680 void *data = sample->raw_data; 726 void *data = sample->raw_data;
681 u64 tmp; /* this is required for casting... */ 727 u64 tmp; /* this is required for casting... */
728 int rc = 0;
682 729
683 tmp = raw_field_value(event, "lockdep_addr", data); 730 tmp = raw_field_value(event, "lockdep_addr", data);
684 memcpy(&release_event.addr, &tmp, sizeof(void *)); 731 memcpy(&release_event.addr, &tmp, sizeof(void *));
685 release_event.name = (char *)raw_field_ptr(event, "name", data); 732 release_event.name = (char *)raw_field_ptr(event, "name", data);
686 733
687 if (trace_handler->acquire_event) 734 if (trace_handler->release_event)
688 trace_handler->release_event(&release_event, sample); 735 rc = trace_handler->release_event(&release_event, sample);
736
737 return rc;
689} 738}
690 739
691static void perf_evsel__process_lock_event(struct perf_evsel *evsel, 740static int perf_evsel__process_lock_event(struct perf_evsel *evsel,
692 struct perf_sample *sample) 741 struct perf_sample *sample)
693{ 742{
694 struct event_format *event = evsel->tp_format; 743 struct event_format *event = evsel->tp_format;
744 int rc = 0;
695 745
696 if (!strcmp(event->name, "lock_acquire")) 746 if (!strcmp(event->name, "lock_acquire"))
697 perf_evsel__process_lock_acquire(evsel, sample); 747 rc = perf_evsel__process_lock_acquire(evsel, sample);
698 if (!strcmp(event->name, "lock_acquired")) 748 if (!strcmp(event->name, "lock_acquired"))
699 perf_evsel__process_lock_acquired(evsel, sample); 749 rc = perf_evsel__process_lock_acquired(evsel, sample);
700 if (!strcmp(event->name, "lock_contended")) 750 if (!strcmp(event->name, "lock_contended"))
701 perf_evsel__process_lock_contended(evsel, sample); 751 rc = perf_evsel__process_lock_contended(evsel, sample);
702 if (!strcmp(event->name, "lock_release")) 752 if (!strcmp(event->name, "lock_release"))
703 perf_evsel__process_lock_release(evsel, sample); 753 rc = perf_evsel__process_lock_release(evsel, sample);
754
755 return rc;
704} 756}
705 757
706static void print_bad_events(int bad, int total) 758static void print_bad_events(int bad, int total)
@@ -802,14 +854,20 @@ static void dump_map(void)
802 } 854 }
803} 855}
804 856
805static void dump_info(void) 857static int dump_info(void)
806{ 858{
859 int rc = 0;
860
807 if (info_threads) 861 if (info_threads)
808 dump_threads(); 862 dump_threads();
809 else if (info_map) 863 else if (info_map)
810 dump_map(); 864 dump_map();
811 else 865 else {
812 die("Unknown type of information\n"); 866 rc = -1;
867 pr_err("Unknown type of information\n");
868 }
869
870 return rc;
813} 871}
814 872
815static int process_sample_event(struct perf_tool *tool __used, 873static int process_sample_event(struct perf_tool *tool __used,
@@ -826,8 +884,7 @@ static int process_sample_event(struct perf_tool *tool __used,
826 return -1; 884 return -1;
827 } 885 }
828 886
829 perf_evsel__process_lock_event(evsel, sample); 887 return perf_evsel__process_lock_event(evsel, sample);
830 return 0;
831} 888}
832 889
833static struct perf_tool eops = { 890static struct perf_tool eops = {
@@ -839,8 +896,10 @@ static struct perf_tool eops = {
839static int read_events(void) 896static int read_events(void)
840{ 897{
841 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); 898 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
842 if (!session) 899 if (!session) {
843 die("Initializing perf session failed\n"); 900 pr_err("Initializing perf session failed\n");
901 return -1;
902 }
844 903
845 return perf_session__process_events(session, &eops); 904 return perf_session__process_events(session, &eops);
846} 905}
@@ -857,13 +916,18 @@ static void sort_result(void)
857 } 916 }
858} 917}
859 918
860static void __cmd_report(void) 919static int __cmd_report(void)
861{ 920{
862 setup_pager(); 921 setup_pager();
863 select_key(); 922
864 read_events(); 923 if ((select_key() != 0) ||
924 (read_events() != 0))
925 return -1;
926
865 sort_result(); 927 sort_result();
866 print_result(); 928 print_result();
929
930 return 0;
867} 931}
868 932
869static const char * const report_usage[] = { 933static const char * const report_usage[] = {
@@ -959,6 +1023,7 @@ static int __cmd_record(int argc, const char **argv)
959int cmd_lock(int argc, const char **argv, const char *prefix __used) 1023int cmd_lock(int argc, const char **argv, const char *prefix __used)
960{ 1024{
961 unsigned int i; 1025 unsigned int i;
1026 int rc = 0;
962 1027
963 symbol__init(); 1028 symbol__init();
964 for (i = 0; i < LOCKHASH_SIZE; i++) 1029 for (i = 0; i < LOCKHASH_SIZE; i++)
@@ -993,11 +1058,13 @@ int cmd_lock(int argc, const char **argv, const char *prefix __used)
993 /* recycling report_lock_ops */ 1058 /* recycling report_lock_ops */
994 trace_handler = &report_lock_ops; 1059 trace_handler = &report_lock_ops;
995 setup_pager(); 1060 setup_pager();
996 read_events(); 1061 if (read_events() != 0)
997 dump_info(); 1062 rc = -1;
1063 else
1064 rc = dump_info();
998 } else { 1065 } else {
999 usage_with_options(lock_usage, lock_options); 1066 usage_with_options(lock_usage, lock_options);
1000 } 1067 }
1001 1068
1002 return 0; 1069 return rc;
1003} 1070}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 479ff2a038f..7b8b891d4d5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -71,19 +71,23 @@ static void advance_output(struct perf_record *rec, size_t size)
71 rec->bytes_written += size; 71 rec->bytes_written += size;
72} 72}
73 73
74static void write_output(struct perf_record *rec, void *buf, size_t size) 74static int write_output(struct perf_record *rec, void *buf, size_t size)
75{ 75{
76 while (size) { 76 while (size) {
77 int ret = write(rec->output, buf, size); 77 int ret = write(rec->output, buf, size);
78 78
79 if (ret < 0) 79 if (ret < 0) {
80 die("failed to write"); 80 pr_err("failed to write\n");
81 return -1;
82 }
81 83
82 size -= ret; 84 size -= ret;
83 buf += ret; 85 buf += ret;
84 86
85 rec->bytes_written += ret; 87 rec->bytes_written += ret;
86 } 88 }
89
90 return 0;
87} 91}
88 92
89static int process_synthesized_event(struct perf_tool *tool, 93static int process_synthesized_event(struct perf_tool *tool,
@@ -92,11 +96,13 @@ static int process_synthesized_event(struct perf_tool *tool,
92 struct machine *machine __used) 96 struct machine *machine __used)
93{ 97{
94 struct perf_record *rec = container_of(tool, struct perf_record, tool); 98 struct perf_record *rec = container_of(tool, struct perf_record, tool);
95 write_output(rec, event, event->header.size); 99 if (write_output(rec, event, event->header.size) < 0)
100 return -1;
101
96 return 0; 102 return 0;
97} 103}
98 104
99static void perf_record__mmap_read(struct perf_record *rec, 105static int perf_record__mmap_read(struct perf_record *rec,
100 struct perf_mmap *md) 106 struct perf_mmap *md)
101{ 107{
102 unsigned int head = perf_mmap__read_head(md); 108 unsigned int head = perf_mmap__read_head(md);
@@ -104,9 +110,10 @@ static void perf_record__mmap_read(struct perf_record *rec,
104 unsigned char *data = md->base + rec->page_size; 110 unsigned char *data = md->base + rec->page_size;
105 unsigned long size; 111 unsigned long size;
106 void *buf; 112 void *buf;
113 int rc = 0;
107 114
108 if (old == head) 115 if (old == head)
109 return; 116 return 0;
110 117
111 rec->samples++; 118 rec->samples++;
112 119
@@ -117,17 +124,26 @@ static void perf_record__mmap_read(struct perf_record *rec,
117 size = md->mask + 1 - (old & md->mask); 124 size = md->mask + 1 - (old & md->mask);
118 old += size; 125 old += size;
119 126
120 write_output(rec, buf, size); 127 if (write_output(rec, buf, size) < 0) {
128 rc = -1;
129 goto out;
130 }
121 } 131 }
122 132
123 buf = &data[old & md->mask]; 133 buf = &data[old & md->mask];
124 size = head - old; 134 size = head - old;
125 old += size; 135 old += size;
126 136
127 write_output(rec, buf, size); 137 if (write_output(rec, buf, size) < 0) {
138 rc = -1;
139 goto out;
140 }
128 141
129 md->prev = old; 142 md->prev = old;
130 perf_mmap__write_tail(md, old); 143 perf_mmap__write_tail(md, old);
144
145out:
146 return rc;
131} 147}
132 148
133static volatile int done = 0; 149static volatile int done = 0;
@@ -183,12 +199,13 @@ static bool perf_evlist__equal(struct perf_evlist *evlist,
183 return true; 199 return true;
184} 200}
185 201
186static void perf_record__open(struct perf_record *rec) 202static int perf_record__open(struct perf_record *rec)
187{ 203{
188 struct perf_evsel *pos; 204 struct perf_evsel *pos;
189 struct perf_evlist *evlist = rec->evlist; 205 struct perf_evlist *evlist = rec->evlist;
190 struct perf_session *session = rec->session; 206 struct perf_session *session = rec->session;
191 struct perf_record_opts *opts = &rec->opts; 207 struct perf_record_opts *opts = &rec->opts;
208 int rc = 0;
192 209
193 perf_evlist__config_attrs(evlist, opts); 210 perf_evlist__config_attrs(evlist, opts);
194 211
@@ -222,10 +239,13 @@ try_again:
222 239
223 if (err == EPERM || err == EACCES) { 240 if (err == EPERM || err == EACCES) {
224 ui__error_paranoid(); 241 ui__error_paranoid();
225 exit(EXIT_FAILURE); 242 rc = -err;
243 goto out;
226 } else if (err == ENODEV && opts->target.cpu_list) { 244 } else if (err == ENODEV && opts->target.cpu_list) {
227 die("No such device - did you specify" 245 pr_err("No such device - did you specify"
228 " an out-of-range profile CPU?\n"); 246 " an out-of-range profile CPU?\n");
247 rc = -err;
248 goto out;
229 } else if (err == EINVAL) { 249 } else if (err == EINVAL) {
230 if (!opts->exclude_guest_missing && 250 if (!opts->exclude_guest_missing &&
231 (attr->exclude_guest || attr->exclude_host)) { 251 (attr->exclude_guest || attr->exclude_host)) {
@@ -272,7 +292,8 @@ try_again:
272 if (err == ENOENT) { 292 if (err == ENOENT) {
273 ui__error("The %s event is not supported.\n", 293 ui__error("The %s event is not supported.\n",
274 perf_evsel__name(pos)); 294 perf_evsel__name(pos));
275 exit(EXIT_FAILURE); 295 rc = -err;
296 goto out;
276 } 297 }
277 298
278 printf("\n"); 299 printf("\n");
@@ -280,34 +301,46 @@ try_again:
280 err, strerror(err)); 301 err, strerror(err));
281 302
282#if defined(__i386__) || defined(__x86_64__) 303#if defined(__i386__) || defined(__x86_64__)
283 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP) 304 if (attr->type == PERF_TYPE_HARDWARE &&
284 die("No hardware sampling interrupt available." 305 err == EOPNOTSUPP) {
285 " No APIC? If so then you can boot the kernel" 306 pr_err("No hardware sampling interrupt available."
286 " with the \"lapic\" boot parameter to" 307 " No APIC? If so then you can boot the kernel"
287 " force-enable it.\n"); 308 " with the \"lapic\" boot parameter to"
309 " force-enable it.\n");
310 rc = -err;
311 goto out;
312 }
288#endif 313#endif
289 314
290 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 315 pr_err("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
316 rc = -err;
317 goto out;
291 } 318 }
292 } 319 }
293 320
294 if (perf_evlist__set_filters(evlist)) { 321 if (perf_evlist__set_filters(evlist)) {
295 error("failed to set filter with %d (%s)\n", errno, 322 error("failed to set filter with %d (%s)\n", errno,
296 strerror(errno)); 323 strerror(errno));
297 exit(-1); 324 rc = -1;
325 goto out;
298 } 326 }
299 327
300 if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { 328 if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) {
301 if (errno == EPERM) 329 if (errno == EPERM) {
302 die("Permission error mapping pages.\n" 330 pr_err("Permission error mapping pages.\n"
303 "Consider increasing " 331 "Consider increasing "
304 "/proc/sys/kernel/perf_event_mlock_kb,\n" 332 "/proc/sys/kernel/perf_event_mlock_kb,\n"
305 "or try again with a smaller value of -m/--mmap_pages.\n" 333 "or try again with a smaller value of -m/--mmap_pages.\n"
306 "(current value: %d)\n", opts->mmap_pages); 334 "(current value: %d)\n", opts->mmap_pages);
307 else if (!is_power_of_2(opts->mmap_pages)) 335 rc = -errno;
308 die("--mmap_pages/-m value must be a power of two."); 336 } else if (!is_power_of_2(opts->mmap_pages)) {
309 337 pr_err("--mmap_pages/-m value must be a power of two.");
310 die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 338 rc = -EINVAL;
339 } else {
340 pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
341 rc = -errno;
342 }
343 goto out;
311 } 344 }
312 345
313 if (rec->file_new) 346 if (rec->file_new)
@@ -315,11 +348,14 @@ try_again:
315 else { 348 else {
316 if (!perf_evlist__equal(session->evlist, evlist)) { 349 if (!perf_evlist__equal(session->evlist, evlist)) {
317 fprintf(stderr, "incompatible append\n"); 350 fprintf(stderr, "incompatible append\n");
318 exit(-1); 351 rc = -1;
352 goto out;
319 } 353 }
320 } 354 }
321 355
322 perf_session__set_id_hdr_size(session); 356 perf_session__set_id_hdr_size(session);
357out:
358 return rc;
323} 359}
324 360
325static int process_buildids(struct perf_record *rec) 361static int process_buildids(struct perf_record *rec)
@@ -335,10 +371,13 @@ static int process_buildids(struct perf_record *rec)
335 size, &build_id__mark_dso_hit_ops); 371 size, &build_id__mark_dso_hit_ops);
336} 372}
337 373
338static void perf_record__exit(int status __used, void *arg) 374static void perf_record__exit(int status, void *arg)
339{ 375{
340 struct perf_record *rec = arg; 376 struct perf_record *rec = arg;
341 377
378 if (status != 0)
379 return;
380
342 if (!rec->opts.pipe_output) { 381 if (!rec->opts.pipe_output) {
343 rec->session->header.data_size += rec->bytes_written; 382 rec->session->header.data_size += rec->bytes_written;
344 383
@@ -393,17 +432,26 @@ static struct perf_event_header finished_round_event = {
393 .type = PERF_RECORD_FINISHED_ROUND, 432 .type = PERF_RECORD_FINISHED_ROUND,
394}; 433};
395 434
396static void perf_record__mmap_read_all(struct perf_record *rec) 435static int perf_record__mmap_read_all(struct perf_record *rec)
397{ 436{
398 int i; 437 int i;
438 int rc = 0;
399 439
400 for (i = 0; i < rec->evlist->nr_mmaps; i++) { 440 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
401 if (rec->evlist->mmap[i].base) 441 if (rec->evlist->mmap[i].base) {
402 perf_record__mmap_read(rec, &rec->evlist->mmap[i]); 442 if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) {
443 rc = -1;
444 goto out;
445 }
446 }
403 } 447 }
404 448
405 if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) 449 if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
406 write_output(rec, &finished_round_event, sizeof(finished_round_event)); 450 rc = write_output(rec, &finished_round_event,
451 sizeof(finished_round_event));
452
453out:
454 return rc;
407} 455}
408 456
409static int __cmd_record(struct perf_record *rec, int argc, const char **argv) 457static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
@@ -463,7 +511,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
463 output = open(output_name, flags, S_IRUSR | S_IWUSR); 511 output = open(output_name, flags, S_IRUSR | S_IWUSR);
464 if (output < 0) { 512 if (output < 0) {
465 perror("failed to create output file"); 513 perror("failed to create output file");
466 exit(-1); 514 return -1;
467 } 515 }
468 516
469 rec->output = output; 517 rec->output = output;
@@ -503,7 +551,10 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
503 } 551 }
504 } 552 }
505 553
506 perf_record__open(rec); 554 if (perf_record__open(rec) != 0) {
555 err = -1;
556 goto out_delete_session;
557 }
507 558
508 /* 559 /*
509 * perf_session__delete(session) will be called at perf_record__exit() 560 * perf_session__delete(session) will be called at perf_record__exit()
@@ -513,19 +564,20 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
513 if (opts->pipe_output) { 564 if (opts->pipe_output) {
514 err = perf_header__write_pipe(output); 565 err = perf_header__write_pipe(output);
515 if (err < 0) 566 if (err < 0)
516 return err; 567 goto out_delete_session;
517 } else if (rec->file_new) { 568 } else if (rec->file_new) {
518 err = perf_session__write_header(session, evsel_list, 569 err = perf_session__write_header(session, evsel_list,
519 output, false); 570 output, false);
520 if (err < 0) 571 if (err < 0)
521 return err; 572 goto out_delete_session;
522 } 573 }
523 574
524 if (!rec->no_buildid 575 if (!rec->no_buildid
525 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { 576 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
526 pr_err("Couldn't generate buildids. " 577 pr_err("Couldn't generate buildids. "
527 "Use --no-buildid to profile anyway.\n"); 578 "Use --no-buildid to profile anyway.\n");
528 return -1; 579 err = -1;
580 goto out_delete_session;
529 } 581 }
530 582
531 rec->post_processing_offset = lseek(output, 0, SEEK_CUR); 583 rec->post_processing_offset = lseek(output, 0, SEEK_CUR);
@@ -533,7 +585,8 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
533 machine = perf_session__find_host_machine(session); 585 machine = perf_session__find_host_machine(session);
534 if (!machine) { 586 if (!machine) {
535 pr_err("Couldn't find native kernel information.\n"); 587 pr_err("Couldn't find native kernel information.\n");
536 return -1; 588 err = -1;
589 goto out_delete_session;
537 } 590 }
538 591
539 if (opts->pipe_output) { 592 if (opts->pipe_output) {
@@ -541,14 +594,14 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
541 process_synthesized_event); 594 process_synthesized_event);
542 if (err < 0) { 595 if (err < 0) {
543 pr_err("Couldn't synthesize attrs.\n"); 596 pr_err("Couldn't synthesize attrs.\n");
544 return err; 597 goto out_delete_session;
545 } 598 }
546 599
547 err = perf_event__synthesize_event_types(tool, process_synthesized_event, 600 err = perf_event__synthesize_event_types(tool, process_synthesized_event,
548 machine); 601 machine);
549 if (err < 0) { 602 if (err < 0) {
550 pr_err("Couldn't synthesize event_types.\n"); 603 pr_err("Couldn't synthesize event_types.\n");
551 return err; 604 goto out_delete_session;
552 } 605 }
553 606
554 if (have_tracepoints(&evsel_list->entries)) { 607 if (have_tracepoints(&evsel_list->entries)) {
@@ -564,7 +617,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
564 process_synthesized_event); 617 process_synthesized_event);
565 if (err <= 0) { 618 if (err <= 0) {
566 pr_err("Couldn't record tracing data.\n"); 619 pr_err("Couldn't record tracing data.\n");
567 return err; 620 goto out_delete_session;
568 } 621 }
569 advance_output(rec, err); 622 advance_output(rec, err);
570 } 623 }
@@ -592,20 +645,24 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
592 perf_event__synthesize_guest_os); 645 perf_event__synthesize_guest_os);
593 646
594 if (!opts->target.system_wide) 647 if (!opts->target.system_wide)
595 perf_event__synthesize_thread_map(tool, evsel_list->threads, 648 err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
596 process_synthesized_event, 649 process_synthesized_event,
597 machine); 650 machine);
598 else 651 else
599 perf_event__synthesize_threads(tool, process_synthesized_event, 652 err = perf_event__synthesize_threads(tool, process_synthesized_event,
600 machine); 653 machine);
601 654
655 if (err != 0)
656 goto out_delete_session;
657
602 if (rec->realtime_prio) { 658 if (rec->realtime_prio) {
603 struct sched_param param; 659 struct sched_param param;
604 660
605 param.sched_priority = rec->realtime_prio; 661 param.sched_priority = rec->realtime_prio;
606 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 662 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
607 pr_err("Could not set realtime priority.\n"); 663 pr_err("Could not set realtime priority.\n");
608 exit(-1); 664 err = -1;
665 goto out_delete_session;
609 } 666 }
610 } 667 }
611 668
@@ -620,7 +677,10 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
620 for (;;) { 677 for (;;) {
621 int hits = rec->samples; 678 int hits = rec->samples;
622 679
623 perf_record__mmap_read_all(rec); 680 if (perf_record__mmap_read_all(rec) < 0) {
681 err = -1;
682 goto out_delete_session;
683 }
624 684
625 if (hits == rec->samples) { 685 if (hits == rec->samples) {
626 if (done) 686 if (done)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index d61825371ad..1f8d11b4f7f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -638,6 +638,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
638 "Show a column with the sum of periods"), 638 "Show a column with the sum of periods"),
639 OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "", 639 OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "",
640 "use branch records for histogram filling", parse_branch_mode), 640 "use branch records for histogram filling", parse_branch_mode),
641 OPT_STRING(0, "objdump", &objdump_path, "path",
642 "objdump binary to use for disassembly and annotations"),
641 OPT_END() 643 OPT_END()
642 }; 644 };
643 645
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 2d6e3b226aa..c350cfee315 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1153,18 +1153,23 @@ static const struct option options[] = {
1153 OPT_END() 1153 OPT_END()
1154}; 1154};
1155 1155
1156static bool have_cmd(int argc, const char **argv) 1156static int have_cmd(int argc, const char **argv)
1157{ 1157{
1158 char **__argv = malloc(sizeof(const char *) * argc); 1158 char **__argv = malloc(sizeof(const char *) * argc);
1159 1159
1160 if (!__argv) 1160 if (!__argv) {
1161 die("malloc"); 1161 pr_err("malloc failed\n");
1162 return -1;
1163 }
1164
1162 memcpy(__argv, argv, sizeof(const char *) * argc); 1165 memcpy(__argv, argv, sizeof(const char *) * argc);
1163 argc = parse_options(argc, (const char **)__argv, record_options, 1166 argc = parse_options(argc, (const char **)__argv, record_options,
1164 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 1167 NULL, PARSE_OPT_STOP_AT_NON_OPTION);
1165 free(__argv); 1168 free(__argv);
1166 1169
1167 return argc != 0; 1170 system_wide = (argc == 0);
1171
1172 return 0;
1168} 1173}
1169 1174
1170int cmd_script(int argc, const char **argv, const char *prefix __used) 1175int cmd_script(int argc, const char **argv, const char *prefix __used)
@@ -1231,13 +1236,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1231 1236
1232 if (pipe(live_pipe) < 0) { 1237 if (pipe(live_pipe) < 0) {
1233 perror("failed to create pipe"); 1238 perror("failed to create pipe");
1234 exit(-1); 1239 return -1;
1235 } 1240 }
1236 1241
1237 pid = fork(); 1242 pid = fork();
1238 if (pid < 0) { 1243 if (pid < 0) {
1239 perror("failed to fork"); 1244 perror("failed to fork");
1240 exit(-1); 1245 return -1;
1241 } 1246 }
1242 1247
1243 if (!pid) { 1248 if (!pid) {
@@ -1249,13 +1254,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1249 if (is_top_script(argv[0])) { 1254 if (is_top_script(argv[0])) {
1250 system_wide = true; 1255 system_wide = true;
1251 } else if (!system_wide) { 1256 } else if (!system_wide) {
1252 system_wide = !have_cmd(argc - rep_args, 1257 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
1253 &argv[rep_args]); 1258 err = -1;
1259 goto out;
1260 }
1254 } 1261 }
1255 1262
1256 __argv = malloc((argc + 6) * sizeof(const char *)); 1263 __argv = malloc((argc + 6) * sizeof(const char *));
1257 if (!__argv) 1264 if (!__argv) {
1258 die("malloc"); 1265 pr_err("malloc failed\n");
1266 err = -ENOMEM;
1267 goto out;
1268 }
1259 1269
1260 __argv[j++] = "/bin/sh"; 1270 __argv[j++] = "/bin/sh";
1261 __argv[j++] = rec_script_path; 1271 __argv[j++] = rec_script_path;
@@ -1277,8 +1287,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1277 close(live_pipe[1]); 1287 close(live_pipe[1]);
1278 1288
1279 __argv = malloc((argc + 4) * sizeof(const char *)); 1289 __argv = malloc((argc + 4) * sizeof(const char *));
1280 if (!__argv) 1290 if (!__argv) {
1281 die("malloc"); 1291 pr_err("malloc failed\n");
1292 err = -ENOMEM;
1293 goto out;
1294 }
1295
1282 j = 0; 1296 j = 0;
1283 __argv[j++] = "/bin/sh"; 1297 __argv[j++] = "/bin/sh";
1284 __argv[j++] = rep_script_path; 1298 __argv[j++] = rep_script_path;
@@ -1303,12 +1317,20 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1303 1317
1304 if (!rec_script_path) 1318 if (!rec_script_path)
1305 system_wide = false; 1319 system_wide = false;
1306 else if (!system_wide) 1320 else if (!system_wide) {
1307 system_wide = !have_cmd(argc - 1, &argv[1]); 1321 if (have_cmd(argc - 1, &argv[1]) != 0) {
1322 err = -1;
1323 goto out;
1324 }
1325 }
1308 1326
1309 __argv = malloc((argc + 2) * sizeof(const char *)); 1327 __argv = malloc((argc + 2) * sizeof(const char *));
1310 if (!__argv) 1328 if (!__argv) {
1311 die("malloc"); 1329 pr_err("malloc failed\n");
1330 err = -ENOMEM;
1331 goto out;
1332 }
1333
1312 __argv[j++] = "/bin/sh"; 1334 __argv[j++] = "/bin/sh";
1313 __argv[j++] = script_path; 1335 __argv[j++] = script_path;
1314 if (system_wide) 1336 if (system_wide)
@@ -1357,18 +1379,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1357 input = open(session->filename, O_RDONLY); /* input_name */ 1379 input = open(session->filename, O_RDONLY); /* input_name */
1358 if (input < 0) { 1380 if (input < 0) {
1359 perror("failed to open file"); 1381 perror("failed to open file");
1360 exit(-1); 1382 return -1;
1361 } 1383 }
1362 1384
1363 err = fstat(input, &perf_stat); 1385 err = fstat(input, &perf_stat);
1364 if (err < 0) { 1386 if (err < 0) {
1365 perror("failed to stat file"); 1387 perror("failed to stat file");
1366 exit(-1); 1388 return -1;
1367 } 1389 }
1368 1390
1369 if (!perf_stat.st_size) { 1391 if (!perf_stat.st_size) {
1370 fprintf(stderr, "zero-sized file, nothing to do!\n"); 1392 fprintf(stderr, "zero-sized file, nothing to do!\n");
1371 exit(0); 1393 return 0;
1372 } 1394 }
1373 1395
1374 scripting_ops = script_spec__lookup(generate_script_lang); 1396 scripting_ops = script_spec__lookup(generate_script_lang);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index d53d8ab099b..02f49eba677 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -428,7 +428,7 @@ static int run_perf_stat(int argc __used, const char **argv)
428 428
429 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { 429 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
430 perror("failed to create pipes"); 430 perror("failed to create pipes");
431 exit(1); 431 return -1;
432 } 432 }
433 433
434 if (forks) { 434 if (forks) {
@@ -510,7 +510,8 @@ static int run_perf_stat(int argc __used, const char **argv)
510 } 510 }
511 if (child_pid != -1) 511 if (child_pid != -1)
512 kill(child_pid, SIGTERM); 512 kill(child_pid, SIGTERM);
513 die("Not all events could be opened.\n"); 513
514 pr_err("Not all events could be opened.\n");
514 return -1; 515 return -1;
515 } 516 }
516 counter->supported = true; 517 counter->supported = true;
@@ -1189,7 +1190,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1189 output = fopen(output_name, mode); 1190 output = fopen(output_name, mode);
1190 if (!output) { 1191 if (!output) {
1191 perror("failed to create output file"); 1192 perror("failed to create output file");
1192 exit(-1); 1193 return -1;
1193 } 1194 }
1194 clock_gettime(CLOCK_REALTIME, &tm); 1195 clock_gettime(CLOCK_REALTIME, &tm);
1195 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 1196 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 381d5ab8712..cf33e5081c3 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -1092,6 +1092,116 @@ static int test__perf_pmu(void)
1092 return perf_pmu__test(); 1092 return perf_pmu__test();
1093} 1093}
1094 1094
1095static int perf_evsel__roundtrip_cache_name_test(void)
1096{
1097 char name[128];
1098 int type, op, err = 0, ret = 0, i, idx;
1099 struct perf_evsel *evsel;
1100 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
1101
1102 if (evlist == NULL)
1103 return -ENOMEM;
1104
1105 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
1106 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
1107 /* skip invalid cache type */
1108 if (!perf_evsel__is_cache_op_valid(type, op))
1109 continue;
1110
1111 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
1112 __perf_evsel__hw_cache_type_op_res_name(type, op, i,
1113 name, sizeof(name));
1114 err = parse_events(evlist, name, 0);
1115 if (err)
1116 ret = err;
1117 }
1118 }
1119 }
1120
1121 idx = 0;
1122 evsel = perf_evlist__first(evlist);
1123
1124 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
1125 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
1126 /* skip invalid cache type */
1127 if (!perf_evsel__is_cache_op_valid(type, op))
1128 continue;
1129
1130 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
1131 __perf_evsel__hw_cache_type_op_res_name(type, op, i,
1132 name, sizeof(name));
1133 if (evsel->idx != idx)
1134 continue;
1135
1136 ++idx;
1137
1138 if (strcmp(perf_evsel__name(evsel), name)) {
1139 pr_debug("%s != %s\n", perf_evsel__name(evsel), name);
1140 ret = -1;
1141 }
1142
1143 evsel = perf_evsel__next(evsel);
1144 }
1145 }
1146 }
1147
1148 perf_evlist__delete(evlist);
1149 return ret;
1150}
1151
1152static int __perf_evsel__name_array_test(const char *names[], int nr_names)
1153{
1154 int i, err;
1155 struct perf_evsel *evsel;
1156 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
1157
1158 if (evlist == NULL)
1159 return -ENOMEM;
1160
1161 for (i = 0; i < nr_names; ++i) {
1162 err = parse_events(evlist, names[i], 0);
1163 if (err) {
1164 pr_debug("failed to parse event '%s', err %d\n",
1165 names[i], err);
1166 goto out_delete_evlist;
1167 }
1168 }
1169
1170 err = 0;
1171 list_for_each_entry(evsel, &evlist->entries, node) {
1172 if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
1173 --err;
1174 pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
1175 }
1176 }
1177
1178out_delete_evlist:
1179 perf_evlist__delete(evlist);
1180 return err;
1181}
1182
1183#define perf_evsel__name_array_test(names) \
1184 __perf_evsel__name_array_test(names, ARRAY_SIZE(names))
1185
1186static int perf_evsel__roundtrip_name_test(void)
1187{
1188 int err = 0, ret = 0;
1189
1190 err = perf_evsel__name_array_test(perf_evsel__hw_names);
1191 if (err)
1192 ret = err;
1193
1194 err = perf_evsel__name_array_test(perf_evsel__sw_names);
1195 if (err)
1196 ret = err;
1197
1198 err = perf_evsel__roundtrip_cache_name_test();
1199 if (err)
1200 ret = err;
1201
1202 return ret;
1203}
1204
1095static struct test { 1205static struct test {
1096 const char *desc; 1206 const char *desc;
1097 int (*func)(void); 1207 int (*func)(void);
@@ -1135,6 +1245,10 @@ static struct test {
1135 .func = dso__test_data, 1245 .func = dso__test_data,
1136 }, 1246 },
1137 { 1247 {
1248 .desc = "roundtrip evsel->name check",
1249 .func = perf_evsel__roundtrip_name_test,
1250 },
1251 {
1138 .func = NULL, 1252 .func = NULL,
1139 }, 1253 },
1140}; 1254};
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 3a282c0057d..51ef69c9841 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -17,6 +17,7 @@
17#include <pthread.h> 17#include <pthread.h>
18 18
19const char *disassembler_style; 19const char *disassembler_style;
20const char *objdump_path;
20 21
21static struct ins *ins__find(const char *name); 22static struct ins *ins__find(const char *name);
22static int disasm_line__parse(char *line, char **namep, char **rawp); 23static int disasm_line__parse(char *line, char **namep, char **rawp);
@@ -820,9 +821,10 @@ fallback:
820 dso, dso->long_name, sym, sym->name); 821 dso, dso->long_name, sym, sym->name);
821 822
822 snprintf(command, sizeof(command), 823 snprintf(command, sizeof(command),
823 "objdump %s%s --start-address=0x%016" PRIx64 824 "%s %s%s --start-address=0x%016" PRIx64
824 " --stop-address=0x%016" PRIx64 825 " --stop-address=0x%016" PRIx64
825 " -d %s %s -C %s|grep -v %s|expand", 826 " -d %s %s -C %s|grep -v %s|expand",
827 objdump_path ? objdump_path : "objdump",
826 disassembler_style ? "-M " : "", 828 disassembler_style ? "-M " : "",
827 disassembler_style ? disassembler_style : "", 829 disassembler_style ? disassembler_style : "",
828 map__rip_2objdump(map, sym->start), 830 map__rip_2objdump(map, sym->start),
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 78a5692dd71..a6d6bc5d716 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -152,5 +152,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
152#endif 152#endif
153 153
154extern const char *disassembler_style; 154extern const char *disassembler_style;
155extern const char *objdump_path;
155 156
156#endif /* __PERF_ANNOTATE_H */ 157#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 3a0f1a5da91..84ff6f160cd 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -120,7 +120,9 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
120 if (!full) { 120 if (!full) {
121 event->comm.tid = pid; 121 event->comm.tid = pid;
122 122
123 process(tool, event, &synth_sample, machine); 123 if (process(tool, event, &synth_sample, machine) != 0)
124 return -1;
125
124 goto out; 126 goto out;
125 } 127 }
126 128
@@ -151,7 +153,10 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
151 153
152 event->comm.tid = pid; 154 event->comm.tid = pid;
153 155
154 process(tool, event, &synth_sample, machine); 156 if (process(tool, event, &synth_sample, machine) != 0) {
157 tgid = -1;
158 break;
159 }
155 } 160 }
156 161
157 closedir(tasks); 162 closedir(tasks);
@@ -167,6 +172,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
167{ 172{
168 char filename[PATH_MAX]; 173 char filename[PATH_MAX];
169 FILE *fp; 174 FILE *fp;
175 int rc = 0;
170 176
171 snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); 177 snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
172 178
@@ -231,18 +237,22 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
231 event->mmap.pid = tgid; 237 event->mmap.pid = tgid;
232 event->mmap.tid = pid; 238 event->mmap.tid = pid;
233 239
234 process(tool, event, &synth_sample, machine); 240 if (process(tool, event, &synth_sample, machine) != 0) {
241 rc = -1;
242 break;
243 }
235 } 244 }
236 } 245 }
237 246
238 fclose(fp); 247 fclose(fp);
239 return 0; 248 return rc;
240} 249}
241 250
242int perf_event__synthesize_modules(struct perf_tool *tool, 251int perf_event__synthesize_modules(struct perf_tool *tool,
243 perf_event__handler_t process, 252 perf_event__handler_t process,
244 struct machine *machine) 253 struct machine *machine)
245{ 254{
255 int rc = 0;
246 struct rb_node *nd; 256 struct rb_node *nd;
247 struct map_groups *kmaps = &machine->kmaps; 257 struct map_groups *kmaps = &machine->kmaps;
248 union perf_event *event = zalloc((sizeof(event->mmap) + 258 union perf_event *event = zalloc((sizeof(event->mmap) +
@@ -284,11 +294,14 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
284 294
285 memcpy(event->mmap.filename, pos->dso->long_name, 295 memcpy(event->mmap.filename, pos->dso->long_name,
286 pos->dso->long_name_len + 1); 296 pos->dso->long_name_len + 1);
287 process(tool, event, &synth_sample, machine); 297 if (process(tool, event, &synth_sample, machine) != 0) {
298 rc = -1;
299 break;
300 }
288 } 301 }
289 302
290 free(event); 303 free(event);
291 return 0; 304 return rc;
292} 305}
293 306
294static int __event__synthesize_thread(union perf_event *comm_event, 307static int __event__synthesize_thread(union perf_event *comm_event,
@@ -392,12 +405,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
392 if (*end) /* only interested in proper numerical dirents */ 405 if (*end) /* only interested in proper numerical dirents */
393 continue; 406 continue;
394 407
395 __event__synthesize_thread(comm_event, mmap_event, pid, 1, 408 if (__event__synthesize_thread(comm_event, mmap_event, pid, 1,
396 process, tool, machine); 409 process, tool, machine) != 0) {
410 err = -1;
411 goto out_closedir;
412 }
397 } 413 }
398 414
399 closedir(proc);
400 err = 0; 415 err = 0;
416out_closedir:
417 closedir(proc);
401out_free_mmap: 418out_free_mmap:
402 free(mmap_event); 419 free(mmap_event);
403out_free_comm: 420out_free_comm:
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 4774ac1e3d5..892353729c7 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -889,3 +889,16 @@ int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *even
889 struct perf_evsel *evsel = perf_evlist__first(evlist); 889 struct perf_evsel *evsel = perf_evlist__first(evlist);
890 return perf_evsel__parse_sample(evsel, event, sample, swapped); 890 return perf_evsel__parse_sample(evsel, event, sample, swapped);
891} 891}
892
893size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
894{
895 struct perf_evsel *evsel;
896 size_t printed = 0;
897
898 list_for_each_entry(evsel, &evlist->entries, node) {
899 printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
900 perf_evsel__name(evsel));
901 }
902
903 return printed + fprintf(fp, "\n");;
904}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 2ed255792c6..3f2e1e4ccdd 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -143,4 +143,6 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist)
143{ 143{
144 return list_entry(evlist->entries.prev, struct perf_evsel, node); 144 return list_entry(evlist->entries.prev, struct perf_evsel, node);
145} 145}
146
147size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp);
146#endif /* __PERF_EVLIST_H */ 148#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7ff3c8fb736..06f76441547 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -68,7 +68,7 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
68 return evsel; 68 return evsel;
69} 69}
70 70
71static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { 71const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
72 "cycles", 72 "cycles",
73 "instructions", 73 "instructions",
74 "cache-references", 74 "cache-references",
@@ -131,12 +131,12 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size)
131 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); 131 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
132} 132}
133 133
134static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { 134const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = {
135 "cpu-clock", 135 "cpu-clock",
136 "task-clock", 136 "task-clock",
137 "page-faults", 137 "page-faults",
138 "context-switches", 138 "context-switches",
139 "CPU-migrations", 139 "cpu-migrations",
140 "minor-faults", 140 "minor-faults",
141 "major-faults", 141 "major-faults",
142 "alignment-faults", 142 "alignment-faults",
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 94f6ba16747..a3f562cec43 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -97,8 +97,10 @@ extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX]
97 [PERF_EVSEL__MAX_ALIASES]; 97 [PERF_EVSEL__MAX_ALIASES];
98extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] 98extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX]
99 [PERF_EVSEL__MAX_ALIASES]; 99 [PERF_EVSEL__MAX_ALIASES];
100const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] 100extern const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
101 [PERF_EVSEL__MAX_ALIASES]; 101 [PERF_EVSEL__MAX_ALIASES];
102extern const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX];
103extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX];
102int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, 104int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
103 char *bf, size_t size); 105 char *bf, size_t size);
104const char *perf_evsel__name(struct perf_evsel *evsel); 106const char *perf_evsel__name(struct perf_evsel *evsel);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 9696e64c9db..d07bc134e56 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -610,11 +610,10 @@ static int write_event_desc(int fd, struct perf_header *h __used,
610 struct perf_evlist *evlist) 610 struct perf_evlist *evlist)
611{ 611{
612 struct perf_evsel *evsel; 612 struct perf_evsel *evsel;
613 u32 nre = 0, nri, sz; 613 u32 nre, nri, sz;
614 int ret; 614 int ret;
615 615
616 list_for_each_entry(evsel, &evlist->entries, node) 616 nre = evlist->nr_entries;
617 nre++;
618 617
619 /* 618 /*
620 * write number of events 619 * write number of events
@@ -1441,6 +1440,9 @@ static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp)
1441 if (ret != sizeof(pmu_num)) 1440 if (ret != sizeof(pmu_num))
1442 goto error; 1441 goto error;
1443 1442
1443 if (ph->needs_swap)
1444 pmu_num = bswap_32(pmu_num);
1445
1444 if (!pmu_num) { 1446 if (!pmu_num) {
1445 fprintf(fp, "# pmu mappings: not available\n"); 1447 fprintf(fp, "# pmu mappings: not available\n");
1446 return; 1448 return;
@@ -1449,6 +1451,9 @@ static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp)
1449 while (pmu_num) { 1451 while (pmu_num) {
1450 if (read(fd, &type, sizeof(type)) != sizeof(type)) 1452 if (read(fd, &type, sizeof(type)) != sizeof(type))
1451 break; 1453 break;
1454 if (ph->needs_swap)
1455 type = bswap_32(type);
1456
1452 name = do_read_string(fd, ph); 1457 name = do_read_string(fd, ph);
1453 if (!name) 1458 if (!name)
1454 break; 1459 break;
@@ -2290,33 +2295,39 @@ static int read_attr(int fd, struct perf_header *ph,
2290 return ret <= 0 ? -1 : 0; 2295 return ret <= 0 ? -1 : 0;
2291} 2296}
2292 2297
2293static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, 2298static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
2294 struct pevent *pevent) 2299 struct pevent *pevent)
2295{ 2300{
2296 struct event_format *event = pevent_find_event(pevent, 2301 struct event_format *event;
2297 evsel->attr.config);
2298 char bf[128]; 2302 char bf[128];
2299 2303
2304 /* already prepared */
2305 if (evsel->tp_format)
2306 return 0;
2307
2308 event = pevent_find_event(pevent, evsel->attr.config);
2300 if (event == NULL) 2309 if (event == NULL)
2301 return -1; 2310 return -1;
2302 2311
2303 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); 2312 if (!evsel->name) {
2304 evsel->name = strdup(bf); 2313 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
2305 if (event->name == NULL) 2314 evsel->name = strdup(bf);
2306 return -1; 2315 if (evsel->name == NULL)
2316 return -1;
2317 }
2307 2318
2308 evsel->tp_format = event; 2319 evsel->tp_format = event;
2309 return 0; 2320 return 0;
2310} 2321}
2311 2322
2312static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist, 2323static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
2313 struct pevent *pevent) 2324 struct pevent *pevent)
2314{ 2325{
2315 struct perf_evsel *pos; 2326 struct perf_evsel *pos;
2316 2327
2317 list_for_each_entry(pos, &evlist->entries, node) { 2328 list_for_each_entry(pos, &evlist->entries, node) {
2318 if (pos->attr.type == PERF_TYPE_TRACEPOINT && 2329 if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
2319 perf_evsel__set_tracepoint_name(pos, pevent)) 2330 perf_evsel__prepare_tracepoint_event(pos, pevent))
2320 return -1; 2331 return -1;
2321 } 2332 }
2322 2333
@@ -2404,7 +2415,8 @@ int perf_session__read_header(struct perf_session *session, int fd)
2404 2415
2405 lseek(fd, header->data_offset, SEEK_SET); 2416 lseek(fd, header->data_offset, SEEK_SET);
2406 2417
2407 if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent)) 2418 if (perf_evlist__prepare_tracepoint_events(session->evlist,
2419 session->pevent))
2408 goto out_delete_evlist; 2420 goto out_delete_evlist;
2409 2421
2410 header->frozen = 1; 2422 header->frozen = 1;
@@ -2638,7 +2650,8 @@ int perf_event__process_tracing_data(union perf_event *event,
2638 if (size_read + padding != size) 2650 if (size_read + padding != size)
2639 die("tracing data size mismatch"); 2651 die("tracing data size mismatch");
2640 2652
2641 perf_evlist__set_tracepoint_names(session->evlist, session->pevent); 2653 perf_evlist__prepare_tracepoint_events(session->evlist,
2654 session->pevent);
2642 2655
2643 return size_read + padding; 2656 return size_read + padding;
2644} 2657}
diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
index fd530dced9c..77c504ff008 100644
--- a/tools/perf/util/intlist.c
+++ b/tools/perf/util/intlist.c
@@ -52,9 +52,9 @@ int intlist__add(struct intlist *ilist, int i)
52 return rblist__add_node(&ilist->rblist, (void *)((long)i)); 52 return rblist__add_node(&ilist->rblist, (void *)((long)i));
53} 53}
54 54
55void intlist__remove(struct intlist *ilist __used, struct int_node *node) 55void intlist__remove(struct intlist *ilist, struct int_node *node)
56{ 56{
57 int_node__delete(node); 57 rblist__remove_node(&ilist->rblist, &node->rb_node);
58} 58}
59 59
60struct int_node *intlist__find(struct intlist *ilist, int i) 60struct int_node *intlist__find(struct intlist *ilist, int i)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index b24630398b9..a031ee1f54f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -308,7 +308,7 @@ int parse_events_add_cache(struct list_head **list, int *idx,
308 for (i = 0; (i < 2) && (op_result[i]); i++) { 308 for (i = 0; (i < 2) && (op_result[i]); i++) {
309 char *str = op_result[i]; 309 char *str = op_result[i];
310 310
311 snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); 311 n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str);
312 312
313 if (cache_op == -1) { 313 if (cache_op == -1) {
314 cache_op = parse_aliases(str, perf_evsel__hw_cache_op, 314 cache_op = parse_aliases(str, perf_evsel__hw_cache_op,
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index d28001016fb..94e673643bc 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -25,16 +25,16 @@
25#include <ctype.h> 25#include <ctype.h>
26#include <errno.h> 26#include <errno.h>
27 27
28#include "../../perf.h"
29#include "../util.h" 28#include "../util.h"
29#include <EXTERN.h>
30#include <perl.h>
31
32#include "../../perf.h"
30#include "../thread.h" 33#include "../thread.h"
31#include "../event.h" 34#include "../event.h"
32#include "../trace-event.h" 35#include "../trace-event.h"
33#include "../evsel.h" 36#include "../evsel.h"
34 37
35#include <EXTERN.h>
36#include <perl.h>
37
38void boot_Perf__Trace__Context(pTHX_ CV *cv); 38void boot_Perf__Trace__Context(pTHX_ CV *cv);
39void boot_DynaLoader(pTHX_ CV *cv); 39void boot_DynaLoader(pTHX_ CV *cv);
40typedef PerlInterpreter * INTERP; 40typedef PerlInterpreter * INTERP;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index f7bb7ae328d..945375897c2 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -692,7 +692,7 @@ static int perf_session_deliver_event(struct perf_session *session,
692 struct perf_tool *tool, 692 struct perf_tool *tool,
693 u64 file_offset); 693 u64 file_offset);
694 694
695static void flush_sample_queue(struct perf_session *s, 695static int flush_sample_queue(struct perf_session *s,
696 struct perf_tool *tool) 696 struct perf_tool *tool)
697{ 697{
698 struct ordered_samples *os = &s->ordered_samples; 698 struct ordered_samples *os = &s->ordered_samples;
@@ -705,7 +705,7 @@ static void flush_sample_queue(struct perf_session *s,
705 int ret; 705 int ret;
706 706
707 if (!tool->ordered_samples || !limit) 707 if (!tool->ordered_samples || !limit)
708 return; 708 return 0;
709 709
710 list_for_each_entry_safe(iter, tmp, head, list) { 710 list_for_each_entry_safe(iter, tmp, head, list) {
711 if (iter->timestamp > limit) 711 if (iter->timestamp > limit)
@@ -715,9 +715,12 @@ static void flush_sample_queue(struct perf_session *s,
715 s->header.needs_swap); 715 s->header.needs_swap);
716 if (ret) 716 if (ret)
717 pr_err("Can't parse sample, err = %d\n", ret); 717 pr_err("Can't parse sample, err = %d\n", ret);
718 else 718 else {
719 perf_session_deliver_event(s, iter->event, &sample, tool, 719 ret = perf_session_deliver_event(s, iter->event, &sample, tool,
720 iter->file_offset); 720 iter->file_offset);
721 if (ret)
722 return ret;
723 }
721 724
722 os->last_flush = iter->timestamp; 725 os->last_flush = iter->timestamp;
723 list_del(&iter->list); 726 list_del(&iter->list);
@@ -737,6 +740,8 @@ static void flush_sample_queue(struct perf_session *s,
737 } 740 }
738 741
739 os->nr_samples = 0; 742 os->nr_samples = 0;
743
744 return 0;
740} 745}
741 746
742/* 747/*
@@ -782,10 +787,11 @@ static int process_finished_round(struct perf_tool *tool,
782 union perf_event *event __used, 787 union perf_event *event __used,
783 struct perf_session *session) 788 struct perf_session *session)
784{ 789{
785 flush_sample_queue(session, tool); 790 int ret = flush_sample_queue(session, tool);
786 session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; 791 if (!ret)
792 session->ordered_samples.next_flush = session->ordered_samples.max_timestamp;
787 793
788 return 0; 794 return ret;
789} 795}
790 796
791/* The queue is ordered by time */ 797/* The queue is ordered by time */
@@ -1443,7 +1449,7 @@ more:
1443 err = 0; 1449 err = 0;
1444 /* do the final flush for ordered samples */ 1450 /* do the final flush for ordered samples */
1445 session->ordered_samples.next_flush = ULLONG_MAX; 1451 session->ordered_samples.next_flush = ULLONG_MAX;
1446 flush_sample_queue(session, tool); 1452 err = flush_sample_queue(session, tool);
1447out_err: 1453out_err:
1448 perf_session__warn_about_errors(session, tool); 1454 perf_session__warn_about_errors(session, tool);
1449 perf_session_free_sample_buffers(session); 1455 perf_session_free_sample_buffers(session);
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c
index 95856ff3dda..155d8b7078a 100644
--- a/tools/perf/util/strlist.c
+++ b/tools/perf/util/strlist.c
@@ -93,7 +93,7 @@ out:
93 93
94void strlist__remove(struct strlist *slist, struct str_node *snode) 94void strlist__remove(struct strlist *slist, struct str_node *snode)
95{ 95{
96 str_node__delete(snode, slist->dupstr); 96 rblist__remove_node(&slist->rblist, &snode->rb_node);
97} 97}
98 98
99struct str_node *strlist__find(struct strlist *slist, const char *entry) 99struct str_node *strlist__find(struct strlist *slist, const char *entry)
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index 051eaa68095..065528b7563 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -117,8 +117,8 @@ int perf_target__strerror(struct perf_target *target, int errnum,
117 117
118 if (err != buf) { 118 if (err != buf) {
119 size_t len = strlen(err); 119 size_t len = strlen(err);
120 char *c = mempcpy(buf, err, min(buflen - 1, len)); 120 memcpy(buf, err, min(buflen - 1, len));
121 *c = '\0'; 121 *(buf + min(buflen - 1, len)) = '\0';
122 } 122 }
123 123
124 return 0; 124 return 0;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 00a93a91a23..67a371355c7 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -69,11 +69,6 @@
69#include <sys/poll.h> 69#include <sys/poll.h>
70#include <sys/socket.h> 70#include <sys/socket.h>
71#include <sys/ioctl.h> 71#include <sys/ioctl.h>
72#include <sys/select.h>
73#include <netinet/in.h>
74#include <netinet/tcp.h>
75#include <arpa/inet.h>
76#include <netdb.h>
77#include <inttypes.h> 72#include <inttypes.h>
78#include "../../../include/linux/magic.h" 73#include "../../../include/linux/magic.h"
79#include "types.h" 74#include "types.h"