diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-02 13:11:25 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-13 08:06:21 -0500 |
commit | f33cbe72e6166b97d6fa2400cb00a885b47999d7 (patch) | |
tree | 838b627d593e8ddc2b26db819bda78ec88d00a9c /tools/perf/builtin-stat.c | |
parent | 6af206fd911c825b83dd4efb2534a3a34ce77072 (diff) |
perf evlist: Send the errno in the signal when workload fails
When a tool uses perf_evlist__start_workload and the supplied workload
fails (e.g.: its binary wasn't found), perror was being used to print
the error reason.
This is undesirable, as the caller may be a GUI, when it wants to have
total control of the error reporting process.
So move to using sigaction(SA_SIGINFO) + siginfo_t->sa_value->sival_int
to communicate to the caller the errno and let it print it using the UI
of its choosing.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-epgcv7kjq8ll2udqfken92pz@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 1c76c7a66f78..9d0d52d55ee6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include "util/thread.h" | 58 | #include "util/thread.h" |
59 | #include "util/thread_map.h" | 59 | #include "util/thread_map.h" |
60 | 60 | ||
61 | #include <signal.h> | ||
61 | #include <stdlib.h> | 62 | #include <stdlib.h> |
62 | #include <sys/prctl.h> | 63 | #include <sys/prctl.h> |
63 | #include <locale.h> | 64 | #include <locale.h> |
@@ -509,16 +510,17 @@ static void handle_initial_delay(void) | |||
509 | } | 510 | } |
510 | } | 511 | } |
511 | 512 | ||
512 | static volatile bool workload_exec_failed; | 513 | static volatile int workload_exec_errno; |
513 | 514 | ||
514 | /* | 515 | /* |
515 | * perf_evlist__prepare_workload will send a SIGUSR1 | 516 | * perf_evlist__prepare_workload will send a SIGUSR1 |
516 | * if the fork fails, since we asked by setting its | 517 | * if the fork fails, since we asked by setting its |
517 | * want_signal to true. | 518 | * want_signal to true. |
518 | */ | 519 | */ |
519 | static void workload_exec_failed_signal(int signo __maybe_unused) | 520 | static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, |
521 | void *ucontext __maybe_unused) | ||
520 | { | 522 | { |
521 | workload_exec_failed = true; | 523 | workload_exec_errno = info->si_value.sival_int; |
522 | } | 524 | } |
523 | 525 | ||
524 | static int __run_perf_stat(int argc, const char **argv) | 526 | static int __run_perf_stat(int argc, const char **argv) |
@@ -596,13 +598,17 @@ static int __run_perf_stat(int argc, const char **argv) | |||
596 | clock_gettime(CLOCK_MONOTONIC, &ref_time); | 598 | clock_gettime(CLOCK_MONOTONIC, &ref_time); |
597 | 599 | ||
598 | if (forks) { | 600 | if (forks) { |
601 | struct sigaction act = { | ||
602 | .sa_flags = SA_SIGINFO, | ||
603 | .sa_sigaction = workload_exec_failed_signal, | ||
604 | }; | ||
599 | /* | 605 | /* |
600 | * perf_evlist__prepare_workload will, after we call | 606 | * perf_evlist__prepare_workload will, after we call |
601 | * perf_evlist__start_Workload, send a SIGUSR1 if the exec call | 607 | * perf_evlist__start_Workload, send a SIGUSR1 if the exec call |
602 | * fails, that we will catch in workload_signal to flip | 608 | * fails, that we will catch in workload_signal to flip |
603 | * workload_exec_failed. | 609 | * workload_exec_errno. |
604 | */ | 610 | */ |
605 | signal(SIGUSR1, workload_exec_failed_signal); | 611 | sigaction(SIGUSR1, &act, NULL); |
606 | 612 | ||
607 | perf_evlist__start_workload(evsel_list); | 613 | perf_evlist__start_workload(evsel_list); |
608 | handle_initial_delay(); | 614 | handle_initial_delay(); |
@@ -615,8 +621,11 @@ static int __run_perf_stat(int argc, const char **argv) | |||
615 | } | 621 | } |
616 | wait(&status); | 622 | wait(&status); |
617 | 623 | ||
618 | if (workload_exec_failed) | 624 | if (workload_exec_errno) { |
625 | const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); | ||
626 | pr_err("Workload failed: %s\n", emsg); | ||
619 | return -1; | 627 | return -1; |
628 | } | ||
620 | 629 | ||
621 | if (WIFSIGNALED(status)) | 630 | if (WIFSIGNALED(status)) |
622 | psignal(WTERMSIG(status), argv[0]); | 631 | psignal(WTERMSIG(status), argv[0]); |