Re: [PATCH 13/24] perf tools: Allow mmap2 event to synthesize kernel image
From: Arnaldo Carvalho de Melo
Date: Tue Nov 17 2020 - 12:43:38 EST
Em Tue, Nov 17, 2020 at 04:16:51PM +0100, Jiri Olsa escreveu:
> On Tue, Nov 17, 2020 at 09:44:37AM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Nov 17, 2020 at 12:00:42PM +0100, Jiri Olsa escreveu:
> > > Allow mmap2 event to synthesize kernel image,
> > > so we can synthesize kernel build id data in
> > > following changes.
> > >
> > > It's enabled by new symbol_conf.buildid_mmap2
> > > bool, which will be switched in following
> > > changes.
> >
> > Why make this an option? MMAP2 goes back years:
> >
> > 13d7a2410fa637f45 (Stephane Eranian 2013-08-21 12:10:24 +0200 904) * The MMAP2 records are an augmented version of MMAP, they add
> > 13d7a2410fa637f45 (Stephane Eranian 2013-08-21 12:10:24 +0200 905) * maj, min, ino numbers to be used to uniquely identify each mapping
> >
> > Also we unconditionally generate MMAP2 events if the kernel supports it,
> > from evsel__config():
> >
> > attr->mmap = track;
> > attr->mmap2 = track && !perf_missing_features.mmap2;
> >
> > So perhaps we should reuse that logic? I.e. use mmap2 if the kernel
> > supports it?
>
> mmap2 itself is not a problem, the problem is the new
> bit (PERF_RECORD_MISC_MMAP_BUILD_ID) that says there's
> build id in mmap2.. older perf tool won't understand
> that and report will crash
Is this theoretical or have you experienced it?
Would be good to tweak the perf.data reader code to not crash on unknown
bits like that :-\
But by looking at machine__process_mmap2_event() I couldn't imagine how
that would crash.
It would get bogus maj, min, ino, ino_generation, but probably that
wouldn't make it crash.
- Arnaldo
int machine__process_mmap2_event(struct machine *machine,
union perf_event *event,
struct perf_sample *sample)
{
struct thread *thread;
struct map *map;
struct dso_id dso_id = {
.maj = event->mmap2.maj,
.min = event->mmap2.min,
.ino = event->mmap2.ino,
.ino_generation = event->mmap2.ino_generation,
};
int ret = 0;
if (dump_trace)
perf_event__fprintf_mmap2(event, stdout);
if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
sample->cpumode == PERF_RECORD_MISC_KERNEL) {
ret = machine__process_kernel_mmap_event(machine, event);
if (ret < 0)
goto out_problem;
return 0;
}
thread = machine__findnew_thread(machine, event->mmap2.pid,
event->mmap2.tid);
if (thread == NULL)
goto out_problem;
map = map__new(machine, event->mmap2.start,
event->mmap2.len, event->mmap2.pgoff,
&dso_id, event->mmap2.prot,
event->mmap2.flags,
event->mmap2.filename, thread);
if (map == NULL)
goto out_problem_map;
ret = thread__insert_map(thread, map);
if (ret)
goto out_problem_insert;
thread__put(thread);
map__put(map);
return 0;
out_problem_insert:
map__put(map);
out_problem_map:
thread__put(thread);
out_problem:
dump_printf("problem processing PERF_RECORD_MMAP2, skipping event.\n");
return 0;
}