diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-10 09:55:59 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-06-10 10:55:27 -0400 |
| commit | f7b7c26e01e51fe46097e11f179dc71ce7950084 (patch) | |
| tree | 4a542e0c386ceebc306886604337dbe6db50c413 | |
| parent | 4502d77c1d8f15f20c04b92cb96c12d4e465de29 (diff) | |
perf_counter tools: Propagate signals properly
Currently report and stat catch SIGINT (and others) without altering
their exit state. This means that things like:
while :; do perf stat ./foo ; done
Loops become hard-to-interrupt, because bash never sees perf terminate
due to interruption. Fix this.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | tools/perf/builtin-record.c | 12 | ||||
| -rw-r--r-- | tools/perf/builtin-stat.c | 13 |
2 files changed, 25 insertions, 0 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index a5698add2fcb..c10553c3460f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -169,10 +169,21 @@ static void mmap_read(struct mmap_data *md) | |||
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static volatile int done = 0; | 171 | static volatile int done = 0; |
| 172 | static volatile int signr = -1; | ||
| 172 | 173 | ||
| 173 | static void sig_handler(int sig) | 174 | static void sig_handler(int sig) |
| 174 | { | 175 | { |
| 175 | done = 1; | 176 | done = 1; |
| 177 | signr = sig; | ||
| 178 | } | ||
| 179 | |||
| 180 | static void sig_atexit(void) | ||
| 181 | { | ||
| 182 | if (signr == -1) | ||
| 183 | return; | ||
| 184 | |||
| 185 | signal(signr, SIG_DFL); | ||
| 186 | kill(getpid(), signr); | ||
| 176 | } | 187 | } |
| 177 | 188 | ||
| 178 | static void pid_synthesize_comm_event(pid_t pid, int full) | 189 | static void pid_synthesize_comm_event(pid_t pid, int full) |
| @@ -459,6 +470,7 @@ static int __cmd_record(int argc, const char **argv) | |||
| 459 | } else for (i = 0; i < nr_cpus; i++) | 470 | } else for (i = 0; i < nr_cpus; i++) |
| 460 | open_counters(i, target_pid); | 471 | open_counters(i, target_pid); |
| 461 | 472 | ||
| 473 | atexit(sig_atexit); | ||
| 462 | signal(SIGCHLD, sig_handler); | 474 | signal(SIGCHLD, sig_handler); |
| 463 | signal(SIGINT, sig_handler); | 475 | signal(SIGINT, sig_handler); |
| 464 | 476 | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 80855090fd9f..6404906924fa 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -296,8 +296,20 @@ static int do_perf_stat(int argc, const char **argv) | |||
| 296 | return 0; | 296 | return 0; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | static volatile int signr = -1; | ||
| 300 | |||
| 299 | static void skip_signal(int signo) | 301 | static void skip_signal(int signo) |
| 300 | { | 302 | { |
| 303 | signr = signo; | ||
| 304 | } | ||
| 305 | |||
| 306 | static void sig_atexit(void) | ||
| 307 | { | ||
| 308 | if (signr == -1) | ||
| 309 | return; | ||
| 310 | |||
| 311 | signal(signr, SIG_DFL); | ||
| 312 | kill(getpid(), signr); | ||
| 301 | } | 313 | } |
| 302 | 314 | ||
| 303 | static const char * const stat_usage[] = { | 315 | static const char * const stat_usage[] = { |
| @@ -345,6 +357,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix) | |||
| 345 | * What we want is for Ctrl-C to work in the exec()-ed | 357 | * What we want is for Ctrl-C to work in the exec()-ed |
| 346 | * task, but being ignored by perf stat itself: | 358 | * task, but being ignored by perf stat itself: |
| 347 | */ | 359 | */ |
| 360 | atexit(sig_atexit); | ||
| 348 | signal(SIGINT, skip_signal); | 361 | signal(SIGINT, skip_signal); |
| 349 | signal(SIGALRM, skip_signal); | 362 | signal(SIGALRM, skip_signal); |
| 350 | signal(SIGABRT, skip_signal); | 363 | signal(SIGABRT, skip_signal); |
