From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753972AbbFSJ2N (ORCPT ); Fri, 19 Jun 2015 05:28:13 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:26283 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753676AbbFSJ2G (ORCPT ); Fri, 19 Jun 2015 05:28:06 -0400 Message-ID: <5583E088.6080202@huawei.com> Date: Fri, 19 Jun 2015 17:27:36 +0800 From: "Wangnan (F)" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Hou Pengyang , , , , CC: Subject: Re: [RFC] perf report: introduce --map-anon-mem for anon-executable-memory symbols parsing References: <1434636076-13502-1-git-send-email-houpengyang@huawei.com> In-Reply-To: <1434636076-13502-1-git-send-email-houpengyang@huawei.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [10.111.66.109] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2015/6/18 22:01, Hou Pengyang wrote: > This patch introduces a --map-anon-mem argument to perf report to deal > with anon-executable-memory symbol parsing. --map-anon-mem is not a good name. The user defined map area list introduced in this patch can be used on not only anon mapping but also file mapping. > > Sometimes, we mmap() executable memory area, and copy some '.so' or '.o' > files to the area, and then do the relocation and code fixing to make the > code work well. However, perf could not parse symbol info in those files, > since the memory area is not file-backended. > > The problem was first discussed in : > https://lkml.org/lkml/2015/4/1/203 > > In this discussion, we finally preferred to something like 'perf inject' > to inject fake mmap events into perf.data. However, for embeded system > whose space is limited, it's not so wise to make another big perf.data > by 'perf inject'. So we still adopt the previous solution: introduce > '--map-anon-mem' argument and let user directly hint perf-report about > the private mapping info. > > The content of this patch: > 1) A new field mapping_strlist is introduced to struct report, in order > to store --map-anon-mem string for afterwards parsing. > 2) A new field maps_anon is introduced to struct map_groups. maps_anon is used > to store the maps user defines directly for anon-mapping. when searching maps > in map_groups, we prefer to the maps stored in maps_anon. > 3) The main part of this patch resides in builtin-report.c and session.c. > the part in builtin-report.c is charge of storing --map-anon-mem string, > while the part in session.c parses the string, create maps, and store maps > in map_groups->maps_anon. > > Here is an example: > $ perf report --map-anon-mem=./libtesta.o@257,0x7f864c0000,0x60,0 \ > --map-anon-mem=./libtestb.o@257,0x7f864c0060,0x1000,0 > > Where 257 is the pid and 0x76864c0000 is private map area got through: > > mmap(NULL, 4096 * 4, PROT_EXEC|PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, \ > -1, 0); > > and libtesta.o is copied to [0x7f864c0000,0x7f864c0060), > libtestb.o is copied to [0x7f864c0060,0x7f864c1060). Please describe how we implement it briefly. > Signed-off-by: Wang Nan > Signed-off-by: Hou Pengyang > --- > tools/perf/Documentation/perf-report.txt | 8 +++ > tools/perf/builtin-report.c | 39 +++++++++++ > tools/perf/util/map.c | 3 +- > tools/perf/util/map.h | 10 ++- > tools/perf/util/session.c | 117 +++++++++++++++++++++++++++++++ > tools/perf/util/session.h | 4 ++ > 6 files changed, 178 insertions(+), 3 deletions(-) > [SNIP] > + > int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) > { > struct perf_session *session; > @@ -728,6 +755,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) > OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", > "Instruction Tracing options", > itrace_parse_synth_opts), > + OPT_CALLBACK_OPTARG(0, "map-anon-mem", &report.mapping_strlist, NULL, > + "objfile@pid,start,length[,offset]", > + "Provide map adjustment hinting", > + append_to_strlist), > OPT_END() > }; > struct perf_data_file file = { > @@ -767,6 +798,14 @@ repeat: > if (session == NULL) > return -1; > > + if (perf_session__map_anon(session, > + report.mapping_strlist)) { > + parse_options_usage(report_usage, options, > + "map-anon-mem", 0); > + goto error; > + } > + > + > if (report.queue_size) { > ordered_events__set_alloc_size(&session->ordered_events, > report.queue_size); > [SNIP] > +static int > +__perf_session__map_anon(struct perf_session *session, int pid, > + char *path, u64 addr, u64 length, > + u64 offset) > +{ > + struct thread *thread; > + struct map *map; > + int err = -1; > + > + thread = perf_session__findnew(session, pid); > + if (!thread) > + return -1; Here is a problem: if there is a FORK event in perf.data for that thread, the thread created here will be cleared, the user defined mapping is also removed. > + > + map = map__new(&session->machines.host, addr, length, offset, > + pid, 0, 0, 0, 0, PROT_READ | PROT_EXEC, 0, path, > + MAP__FUNCTION, thread); > + if (!map) > + goto out; > + > + maps__fixup_overlappings(&thread->mg->maps_anon, map, stderr); > + maps__insert(&thread->mg->maps_anon, map); > + map->groups = thread->mg; > + > + err = 0; > +out: > + thread__put(thread); > + return err; > +} > + > +int perf_session__map_anon(struct perf_session *session, > + struct strlist *slist) > +{ > + struct str_node *node; > + int err; > + > + if (!slist) > + return 0; > + > + strlist__for_each(node, slist) { > + int pid; > + u64 addr, length, offset; > + const char *map_anon_cmd = node->s; > + char path[PATH_MAX]; > + > + if (parse_map_anon_mem(map_anon_cmd, path, > + &pid, &addr, &length, &offset)) > + return -1; > + > + err = __perf_session__map_anon(session, > + pid, path, addr, > + length, offset); > + if (err) > + return -1; > + } > + > + return 0; > +} > [SNIP] I think splitting this patch into small pieces can make it easier to read: perf tools: map: Search user defined map area list before areas get from perf.data perf tools: Creat user defined map area list when creating 'struct thread' perf record: Introduce --custom-map options Thank you.