aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-record.c127
1 files changed, 60 insertions, 67 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 8ce62ef7f6c3..2e0d484068d2 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -147,29 +147,19 @@ static void sig_handler(int sig)
147{ 147{
148 if (sig == SIGCHLD) 148 if (sig == SIGCHLD)
149 child_finished = 1; 149 child_finished = 1;
150 else
151 signr = sig;
150 152
151 done = 1; 153 done = 1;
152 signr = sig;
153} 154}
154 155
155static void record__sig_exit(int exit_status __maybe_unused, void *arg) 156static void record__sig_exit(void)
156{ 157{
157 struct record *rec = arg; 158 if (signr == -1)
158 int status;
159
160 if (rec->evlist->workload.pid > 0) {
161 if (!child_finished)
162 kill(rec->evlist->workload.pid, SIGTERM);
163
164 wait(&status);
165 if (WIFSIGNALED(status))
166 psignal(WTERMSIG(status), rec->progname);
167 }
168
169 if (signr == -1 || signr == SIGUSR1)
170 return; 159 return;
171 160
172 signal(signr, SIG_DFL); 161 signal(signr, SIG_DFL);
162 raise(signr);
173} 163}
174 164
175static int record__open(struct record *rec) 165static int record__open(struct record *rec)
@@ -243,27 +233,6 @@ static int process_buildids(struct record *rec)
243 size, &build_id__mark_dso_hit_ops); 233 size, &build_id__mark_dso_hit_ops);
244} 234}
245 235
246static void record__exit(int status, void *arg)
247{
248 struct record *rec = arg;
249 struct perf_data_file *file = &rec->file;
250
251 if (status != 0)
252 return;
253
254 if (!file->is_pipe) {
255 rec->session->header.data_size += rec->bytes_written;
256
257 if (!rec->no_buildid)
258 process_buildids(rec);
259 perf_session__write_header(rec->session, rec->evlist,
260 file->fd, true);
261 perf_session__delete(rec->session);
262 perf_evlist__delete(rec->evlist);
263 symbol__exit();
264 }
265}
266
267static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 236static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
268{ 237{
269 int err; 238 int err;
@@ -344,18 +313,19 @@ static volatile int workload_exec_errno;
344 * if the fork fails, since we asked by setting its 313 * if the fork fails, since we asked by setting its
345 * want_signal to true. 314 * want_signal to true.
346 */ 315 */
347static void workload_exec_failed_signal(int signo, siginfo_t *info, 316static void workload_exec_failed_signal(int signo __maybe_unused,
317 siginfo_t *info,
348 void *ucontext __maybe_unused) 318 void *ucontext __maybe_unused)
349{ 319{
350 workload_exec_errno = info->si_value.sival_int; 320 workload_exec_errno = info->si_value.sival_int;
351 done = 1; 321 done = 1;
352 signr = signo;
353 child_finished = 1; 322 child_finished = 1;
354} 323}
355 324
356static int __cmd_record(struct record *rec, int argc, const char **argv) 325static int __cmd_record(struct record *rec, int argc, const char **argv)
357{ 326{
358 int err; 327 int err;
328 int status = 0;
359 unsigned long waking = 0; 329 unsigned long waking = 0;
360 const bool forks = argc > 0; 330 const bool forks = argc > 0;
361 struct machine *machine; 331 struct machine *machine;
@@ -367,7 +337,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
367 337
368 rec->progname = argv[0]; 338 rec->progname = argv[0];
369 339
370 on_exit(record__sig_exit, rec); 340 atexit(record__sig_exit);
371 signal(SIGCHLD, sig_handler); 341 signal(SIGCHLD, sig_handler);
372 signal(SIGINT, sig_handler); 342 signal(SIGINT, sig_handler);
373 signal(SIGTERM, sig_handler); 343 signal(SIGTERM, sig_handler);
@@ -388,32 +358,28 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
388 workload_exec_failed_signal); 358 workload_exec_failed_signal);
389 if (err < 0) { 359 if (err < 0) {
390 pr_err("Couldn't run the workload!\n"); 360 pr_err("Couldn't run the workload!\n");
361 status = err;
391 goto out_delete_session; 362 goto out_delete_session;
392 } 363 }
393 } 364 }
394 365
395 if (record__open(rec) != 0) { 366 if (record__open(rec) != 0) {
396 err = -1; 367 err = -1;
397 goto out_delete_session; 368 goto out_child;
398 } 369 }
399 370
400 if (!rec->evlist->nr_groups) 371 if (!rec->evlist->nr_groups)
401 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); 372 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
402 373
403 /*
404 * perf_session__delete(session) will be called at record__exit()
405 */
406 on_exit(record__exit, rec);
407
408 if (file->is_pipe) { 374 if (file->is_pipe) {
409 err = perf_header__write_pipe(file->fd); 375 err = perf_header__write_pipe(file->fd);
410 if (err < 0) 376 if (err < 0)
411 goto out_delete_session; 377 goto out_child;
412 } else { 378 } else {
413 err = perf_session__write_header(session, rec->evlist, 379 err = perf_session__write_header(session, rec->evlist,
414 file->fd, false); 380 file->fd, false);
415 if (err < 0) 381 if (err < 0)
416 goto out_delete_session; 382 goto out_child;
417 } 383 }
418 384
419 if (!rec->no_buildid 385 if (!rec->no_buildid
@@ -421,7 +387,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
421 pr_err("Couldn't generate buildids. " 387 pr_err("Couldn't generate buildids. "
422 "Use --no-buildid to profile anyway.\n"); 388 "Use --no-buildid to profile anyway.\n");
423 err = -1; 389 err = -1;
424 goto out_delete_session; 390 goto out_child;
425 } 391 }
426 392
427 machine = &session->machines.host; 393 machine = &session->machines.host;
@@ -431,7 +397,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
431 process_synthesized_event); 397 process_synthesized_event);
432 if (err < 0) { 398 if (err < 0) {
433 pr_err("Couldn't synthesize attrs.\n"); 399 pr_err("Couldn't synthesize attrs.\n");
434 goto out_delete_session; 400 goto out_child;
435 } 401 }
436 402
437 if (have_tracepoints(&rec->evlist->entries)) { 403 if (have_tracepoints(&rec->evlist->entries)) {
@@ -447,7 +413,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
447 process_synthesized_event); 413 process_synthesized_event);
448 if (err <= 0) { 414 if (err <= 0) {
449 pr_err("Couldn't record tracing data.\n"); 415 pr_err("Couldn't record tracing data.\n");
450 goto out_delete_session; 416 goto out_child;
451 } 417 }
452 rec->bytes_written += err; 418 rec->bytes_written += err;
453 } 419 }
@@ -475,7 +441,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
475 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,