diff options
Diffstat (limited to 'tools/perf/builtin-inject.c')
-rw-r--r-- | tools/perf/builtin-inject.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 61766eead4f4..c8cf2fdd9cff 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -47,7 +47,7 @@ struct guest_event { struct perf_sample sample; union perf_event *event; - char event_buf[PERF_SAMPLE_MAX_SIZE]; + char *event_buf; }; struct guest_id { @@ -122,7 +122,7 @@ struct perf_inject { u64 aux_id; struct list_head samples; struct itrace_synth_opts itrace_synth_opts; - char event_copy[PERF_SAMPLE_MAX_SIZE]; + char *event_copy; struct perf_file_section secs[HEADER_FEAT_BITS]; struct guest_session guest_session; struct strlist *known_build_ids; @@ -320,8 +320,14 @@ perf_inject__cut_auxtrace_sample(struct perf_inject *inject, { size_t sz1 = sample->aux_sample.data - (void *)event; size_t sz2 = event->header.size - sample->aux_sample.size - sz1; - union perf_event *ev = (union perf_event *)inject->event_copy; + union perf_event *ev; + if (inject->event_copy == NULL) { + inject->event_copy = malloc(PERF_SAMPLE_MAX_SIZE); + if (!inject->event_copy) + return ERR_PTR(-ENOMEM); + } + ev = (union perf_event *)inject->event_copy; if (sz1 > event->header.size || sz2 > event->header.size || sz1 + sz2 > event->header.size || sz1 < sizeof(struct perf_event_header) + sizeof(u64)) @@ -357,8 +363,11 @@ static int perf_event__repipe_sample(struct perf_tool *tool, build_id__mark_dso_hit(tool, event, sample, evsel, machine); - if (inject->itrace_synth_opts.set && sample->aux_sample.size) + if (inject->itrace_synth_opts.set && sample->aux_sample.size) { event = perf_inject__cut_auxtrace_sample(inject, event, sample); + if (IS_ERR(event)) + return PTR_ERR(event); + } return perf_event__repipe_synth(tool, event); } @@ -417,7 +426,7 @@ static struct dso *findnew_dso(int pid, int tid, const char *filename, } vdso = is_vdso_map(filename); - nsi = nsinfo__get(thread->nsinfo); + nsi = nsinfo__get(thread__nsinfo(thread)); if (vdso) { /* The vdso maps are always on the host and not the @@ -743,6 +752,7 @@ int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, struct addr_location al; struct thread *thread; + addr_location__init(&al); thread = machine__findnew_thread(machine, sample->pid, sample->tid); if (thread == NULL) { pr_err("problem processing %d event, skipping it.\n", @@ -763,6 +773,7 @@ int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, thread__put(thread); repipe: perf_event__repipe(tool, event, sample, machine); + addr_location__exit(&al); return 0; } @@ -1363,11 +1374,19 @@ static void guest_session__convert_time(struct guest_session *gs, u64 guest_time static int guest_session__fetch(struct guest_session *gs) { - void *buf = gs->ev.event_buf; - struct perf_event_header *hdr = buf; + void *buf; + struct perf_event_header *hdr; size_t hdr_sz = sizeof(*hdr); ssize_t ret; + buf = gs->ev.event_buf; + if (!buf) { + buf = malloc(PERF_SAMPLE_MAX_SIZE); + if (!buf) + return -ENOMEM; + gs->ev.event_buf = buf; + } + hdr = buf; ret = readn(gs->tmp_fd, buf, hdr_sz); if (ret < 0) return ret; @@ -2389,5 +2408,7 @@ out_close_output: if (!inject.in_place_update) perf_data__close(&inject.output); free(inject.itrace_synth_opts.vm_tm_corr_args); + free(inject.event_copy); + free(inject.guest_session.ev.event_buf); return ret; } |