mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 23:58:05 +00:00
perf stat: Avoid sending SIGTERM to random processes
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>
This commit is contained in:
parent
079787f209
commit
d07f0b1206
1 changed files with 22 additions and 1 deletions
|
@ -87,7 +87,7 @@ static int run_count = 1;
|
||||||
static bool no_inherit = false;
|
static bool no_inherit = false;
|
||||||
static bool scale = true;
|
static bool scale = true;
|
||||||
static enum aggr_mode aggr_mode = AGGR_GLOBAL;
|
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 bool null_run = false;
|
||||||
static int detailed_run = 0;
|
static int detailed_run = 0;
|
||||||
static bool big_num = true;
|
static bool big_num = true;
|
||||||
|
@ -1148,13 +1148,34 @@ static void skip_signal(int signo)
|
||||||
done = 1;
|
done = 1;
|
||||||
|
|
||||||
signr = signo;
|
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)
|
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)
|
if (child_pid != -1)
|
||||||
kill(child_pid, SIGTERM);
|
kill(child_pid, SIGTERM);
|
||||||
|
|
||||||
|
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
|
||||||
if (signr == -1)
|
if (signr == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue