Commit de9f498d authored by Changbin Du's avatar Changbin Du Committed by Arnaldo Carvalho de Melo

perf trace: Avoid early exit due SIGCHLD from non-workload processes

The function trace__symbols_init() runs "perf-read-vdso32" and that ends up
with a SIGCHLD delivered to 'perf'. And this SIGCHLD make perf exit early.

'perf trace' should exit only if the SIGCHLD is from our workload process.
So let's use sigaction() instead of signal() to match such condition.

Committer notes:

Use memset to zero the 'struct sigaction' variable as the '= { 0 }'
method isn't accepted in many compiler versions, e.g.:

   4    34.02 alpine:3.6                    : FAIL clang version 4.0.0 (tags/RELEASE_400/final)
    builtin-trace.c:4897:35: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
            struct sigaction sigchld_act = { 0 };
                                             ^
                                             {}
    builtin-trace.c:4897:37: error: missing field 'sa_mask' initializer [-Werror,-Wmissing-field-initializers]
            struct sigaction sigchld_act = { 0 };
                                               ^
    2 errors generated.
   6    32.60 alpine:3.8                    : FAIL gcc version 6.4.0 (Alpine 6.4.0)
    builtin-trace.c:4897:35: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
            struct sigaction sigchld_act = { 0 };
                                             ^
                                             {}
    builtin-trace.c:4897:37: error: missing field 'sa_mask' initializer [-Werror,-Wmissing-field-initializers]
            struct sigaction sigchld_act = { 0 };
                                               ^
    2 errors generated.
   7    34.82 alpine:3.9                    : FAIL gcc version 8.3.0 (Alpine 8.3.0)
    builtin-trace.c:4897:35: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
            struct sigaction sigchld_act = { 0 };
                                             ^
                                             {}
    builtin-trace.c:4897:37: error: missing field 'sa_mask' initializer [-Werror,-Wmissing-field-initializers]
            struct sigaction sigchld_act = { 0 };
                                               ^
    2 errors generated.
Signed-off-by: default avatarChangbin Du <changbin.du@gmail.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220208140725.3947-1-changbin.du@gmail.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 0bc2ba49
...@@ -1536,13 +1536,20 @@ static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) ...@@ -1536,13 +1536,20 @@ static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
return fprintf(fp, " ? "); return fprintf(fp, " ? ");
} }
static pid_t workload_pid = -1;
static bool done = false; static bool done = false;
static bool interrupted = false; static bool interrupted = false;
static void sig_handler(int sig) static void sighandler_interrupt(int sig __maybe_unused)
{ {
done = true; done = interrupted = true;
interrupted = sig == SIGINT; }
static void sighandler_chld(int sig __maybe_unused, siginfo_t *info,
void *context __maybe_unused)
{
if (info->si_pid == workload_pid)
done = true;
} }
static size_t trace__fprintf_comm_tid(struct trace *trace, struct thread *thread, FILE *fp) static size_t trace__fprintf_comm_tid(struct trace *trace, struct thread *thread, FILE *fp)
...@@ -3938,7 +3945,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) ...@@ -3938,7 +3945,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
bool draining = false; bool draining = false;
trace->live = true; trace->live = true;
signal(SIGCHLD, sig_handler);
if (!trace->raw_augmented_syscalls) { if (!trace->raw_augmented_syscalls) {
if (trace->trace_syscalls && trace__add_syscall_newtp(trace)) if (trace->trace_syscalls && trace__add_syscall_newtp(trace))
...@@ -4018,6 +4024,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) ...@@ -4018,6 +4024,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
fprintf(trace->output, "Couldn't run the workload!\n"); fprintf(trace->output, "Couldn't run the workload!\n");
goto out_delete_evlist; goto out_delete_evlist;
} }
workload_pid = evlist->workload.pid;
} }
err = evlist__open(evlist); err = evlist__open(evlist);
...@@ -4887,10 +4894,16 @@ int cmd_trace(int argc, const char **argv) ...@@ -4887,10 +4894,16 @@ int cmd_trace(int argc, const char **argv)
const char * const trace_subcommands[] = { "record", NULL }; const char * const trace_subcommands[] = { "record", NULL };
int err = -1; int err = -1;
char bf[BUFSIZ]; char bf[BUFSIZ];
struct sigaction sigchld_act;
signal(SIGSEGV, sighandler_dump_stack); signal(SIGSEGV, sighandler_dump_stack);
signal(SIGFPE, sighandler_dump_stack); signal(SIGFPE, sighandler_dump_stack);
signal(SIGINT, sig_handler); signal(SIGINT, sighandler_interrupt);
memset(&sigchld_act, 0, sizeof(sigchld_act));
sigchld_act.sa_flags = SA_SIGINFO;
sigchld_act.sa_sigaction = sighandler_chld;
sigaction(SIGCHLD, &sigchld_act, NULL);
trace.evlist = evlist__new(); trace.evlist = evlist__new();
trace.sctbl = syscalltbl__new(); trace.sctbl = syscalltbl__new();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment