perf tools: Make stat/record print fatal signals of the target program
authorAndi Kleen <ak@linux.intel.com>
Thu, 15 Sep 2011 21:31:40 +0000 (14:31 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 29 Sep 2011 20:09:46 +0000 (17:09 -0300)
When a program crashes under perf there is no message about it, unlike
when running it from bash. This can be confusing and lead to wrong
actions during debugging.

Print fatal signals in perf stat/record.

Thanks to Furat Afram for finding the problem originally

Link: http://lkml.kernel.org/r/1316122302-24306-1-git-send-email-andi@firstfloor.org
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-record.c
tools/perf/builtin-stat.c

index 6b0519f885e4ecc436e9344a3c2f94865eafbd92..042117f8fffa3a3ef949237bf7ebcbebc974386a 100644 (file)
@@ -73,6 +73,7 @@ static off_t                  post_processing_offset;
 
 static struct perf_session     *session;
 static const char              *cpu_list;
+static const char               *progname;
 
 static void advance_output(size_t size)
 {
@@ -137,17 +138,29 @@ static void mmap_read(struct perf_mmap *md)
 
 static volatile int done = 0;
 static volatile int signr = -1;
+static volatile int child_finished = 0;
 
 static void sig_handler(int sig)
 {
+       if (sig == SIGCHLD)
+               child_finished = 1;
+
        done = 1;
        signr = sig;
 }
 
 static void sig_atexit(void)
 {
-       if (child_pid > 0)
-               kill(child_pid, SIGTERM);
+       int status;
+
+       if (child_pid > 0) {
+               if (!child_finished)
+                       kill(child_pid, SIGTERM);
+
+               wait(&status);
+               if (WIFSIGNALED(status))
+                       psignal(WTERMSIG(status), progname);
+       }
 
        if (signr == -1 || signr == SIGUSR1)
                return;
@@ -445,6 +458,8 @@ static int __cmd_record(int argc, const char **argv)
        char buf;
        struct machine *machine;
 
+       progname = argv[0];
+
        page_size = sysconf(_SC_PAGE_SIZE);
 
        atexit(sig_atexit);
index b5673194870a9dbef9dd40572f43deeb9bfa326f..7ce65f52415e0799f060d35d67290fac196dfb12 100644 (file)
@@ -495,6 +495,8 @@ static int run_perf_stat(int argc __used, const char **argv)
        if (forks) {
                close(go_pipe[1]);
                wait(&status);
+               if (WIFSIGNALED(status))
+                       psignal(WTERMSIG(status), argv[0]);
        } else {
                while(!done) sleep(1);
        }