Skip to content

Commit

Permalink
perf stat: Avoid sending SIGTERM to random processes
Browse files Browse the repository at this point in the history
This patch fixes a problem with perf stat whereby on termination it may
send a SIGTERM signal to random processes on systems with high PID
recycling. I got some actual bug reports on this.

There is race between the SIGCHLD and sig_atexit() handlers.  This patch
addresses this problem by clearing child_pid in the SIGCHLD handler.

Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20130604154426.GA2928@quad
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Stephane Eranian authored and Arnaldo Carvalho de Melo committed Jul 8, 2013
1 parent 079787f commit d07f0b1
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static int run_count = 1;
static bool no_inherit = false;
static bool scale = true;
static enum aggr_mode aggr_mode = AGGR_GLOBAL;
static pid_t child_pid = -1;
static volatile pid_t child_pid = -1;
static bool null_run = false;
static int detailed_run = 0;
static bool big_num = true;
Expand Down Expand Up @@ -1148,13 +1148,34 @@ static void skip_signal(int signo)
done = 1;

signr = signo;
/*
* render child_pid harmless
* won't send SIGTERM to a random
* process in case of race condition
* and fast PID recycling
*/
child_pid = -1;
}

static void sig_atexit(void)
{
sigset_t set, oset;

/*
* avoid race condition with SIGCHLD handler
* in skip_signal() which is modifying child_pid
* goal is to avoid send SIGTERM to a random
* process
*/
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, &oset);

if (child_pid != -1)
kill(child_pid, SIGTERM);

sigprocmask(SIG_SETMASK, &oset, NULL);

if (signr == -1)
return;

Expand Down

0 comments on commit d07f0b1

Please sign in to comment.