summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 63136d0534d4..771533ced6a8 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -5,10 +5,13 @@
* (or a CPU, or a PID) into the perf.data output file - for
* later analysis via perf report.
*/
+#define _FILE_OFFSET_BITS 64
+
#include "builtin.h"
#include "perf.h"
+#include "util/build-id.h"
#include "util/util.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
@@ -62,6 +65,7 @@ static int nr_poll = 0;
static int nr_cpu = 0;
static int file_new = 1;
+static off_t post_processing_offset;
static struct perf_session *session;
@@ -111,22 +115,10 @@ static void write_output(void *buf, size_t size)
}
}
-static void write_event(event_t *buf, size_t size)
-{
- /*
- * Add it to the list of DSOs, so that when we finish this
- * record session we can pick the available build-ids.
- */
- if (buf->header.type == PERF_RECORD_MMAP)
- dsos__findnew(buf->mmap.filename);
-
- write_output(buf, size);
-}
-
static int process_synthesized_event(event_t *event,
struct perf_session *self __used)
{
- write_event(event, event->header.size);
+ write_output(event, event->header.size);
return 0;
}
@@ -178,14 +170,14 @@ static void mmap_read(struct mmap_data *md)
size = md->mask + 1 - (old & md->mask);
old += size;
- write_event(buf, size);
+ write_output(buf, size);
}
buf = &data[old & md->mask];
size = head - old;
old += size;
- write_event(buf, size);
+ write_output(buf, size);
md->prev = old;
mmap_write_tail(md, old);
@@ -395,14 +387,25 @@ static void open_counters(int cpu, pid_t pid)
nr_cpu++;
}
+static int process_buildids(void)
+{
+ u64 size = lseek(output, 0, SEEK_CUR);
+
+ session->fd = output;
+ return __perf_session__process_events(session, post_processing_offset,
+ size - post_processing_offset,
+ size, &build_id__mark_dso_hit_ops);
+}
+
static void atexit_header(void)
{
session->header.data_size += bytes_written;
+ process_buildids();
perf_header__write(&session->header, output, true);
}
-static int __cmd_record(int argc __used, const char **argv)
+static int __cmd_record(int argc, const char **argv)
{
int i, counter;
struct stat st;
@@ -411,6 +414,7 @@ static int __cmd_record(int argc __used, const char **argv)
int err;
unsigned long waking = 0;
int child_ready_pipe[2], go_pipe[2];
+ const bool forks = target_pid == -1 && argc > 0;
char buf;
page_size = sysconf(_SC_PAGE_SIZE);
@@ -422,7 +426,7 @@ static int __cmd_record(int argc __used, const char **argv)
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
- if (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0) {
+ if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
perror("failed to create pipes");
exit(-1);
}
@@ -483,7 +487,7 @@ static int __cmd_record(int argc __used, const char **argv)
atexit(atexit_header);
- if (target_pid == -1) {
+ if (forks) {
pid = fork();
if (pid < 0) {
perror("failed to fork");
@@ -550,8 +554,23 @@ static int __cmd_record(int argc __used, const char **argv)
return err;
}
- if (!system_wide)
- event__synthesize_thread(pid, process_synthesized_event,
+ post_processing_offset = lseek(output, 0, SEEK_CUR);
+
+ err = event__synthesize_kernel_mmap(process_synthesized_event,
+ session, "_text");
+ if (err < 0) {
+ pr_err("Couldn't record kernel reference relocation symbol.\n");
+ return err;
+ }
+
+ err = event__synthesize_modules(process_synthesized_event, session);
+ if (err < 0) {
+ pr_err("Couldn't record kernel reference relocation symbol.\n");
+ return err;
+ }
+
+ if (!system_wide && profile_cpu == -1)
+ event__synthesize_thread(target_pid, process_synthesized_event,
session);
else
event__synthesize_threads(process_synthesized_event, session);
@@ -569,7 +588,8 @@ static int __cmd_record(int argc __used, const char **argv)
/*
* Let the child rip
*/
- close(go_pipe[1]);
+ if (forks)
+ close(go_pipe[1]);
for (;;) {
int hits = samples;
@@ -667,7 +687,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
argc = parse_options(argc, argv, options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
- if (!argc && target_pid == -1 && (!system_wide || profile_cpu == -1))
+ if (!argc && target_pid == -1 && !system_wide && profile_cpu == -1)
usage_with_options(record_usage, options);
symbol__init();