mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
perf symbols: Fix symbols searching for module in buildid-cache
Before this patch, if a sample is triggered inside a module not in /lib/modules/`uname -r`/, even if the module is in buildid-cache, 'perf report' will still be unable to find the correct symbol. For example: # rm -rf ~/.debug/ # perf buildid-cache -a ./mymodule.ko # perf probe -m ./mymodule.ko -a get_mymodule_val Added new event: probe:get_mymodule_val (on get_mymodule_val in mymodule) You can now use it in all perf tools, such as: perf record -e probe:get_mymodule_val -aR sleep 1 # perf record -e probe:get_mymodule_val cat /proc/mymodule mymodule:3 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ] # perf report --stdio [SNIP] # # Overhead Command Shared Object Symbol # ........ ....... ................ ...................... # 100.00% cat [mymodule] [k] 0x0000000000000001 # perf report -vvvv --stdio dso__load_sym: adjusting symbol: st_value: 0 sh_addr: 0 sh_offset: 0x70 symbol__new: get_mymodule_val 0x70-0x8a [SNIP] This is caused by dso__load() -> dso__load_sym(). In dso__load(), kmod is true only when its file is found in some well know directories. All files loaded from buildid-cache are treated as user programs. Following dso__load_sym() set map->pgoff incorrectly. This patch gives kernel modules in buildid-cache a chance to adjust value of kmod. After dso__load() get the type of symbols, if it is buildid, check the last 3 chars of original filename against '.ko', and adjust the value of kmod if the file is a kernel module. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Cody P Schafer <dev@codyps.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kirill Smelkov <kirr@nexedi.com> Cc: Li Zefan <lizefan@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1454680939-24963-3-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
c7ac24178c
commit
e7ee404757
@ -166,6 +166,50 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
|
||||
return build_id__filename(build_id_hex, bf, size);
|
||||
}
|
||||
|
||||
bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
|
||||
{
|
||||
char *id_name, *ch;
|
||||
struct stat sb;
|
||||
|
||||
id_name = dso__build_id_filename(dso, bf, size);
|
||||
if (!id_name)
|
||||
goto err;
|
||||
if (access(id_name, F_OK))
|
||||
goto err;
|
||||
if (lstat(id_name, &sb) == -1)
|
||||
goto err;
|
||||
if ((size_t)sb.st_size > size - 1)
|
||||
goto err;
|
||||
if (readlink(id_name, bf, size - 1) < 0)
|
||||
goto err;
|
||||
|
||||
bf[sb.st_size] = '\0';
|
||||
|
||||
/*
|
||||
* link should be:
|
||||
* ../../lib/modules/4.4.0-rc4/kernel/net/ipv4/netfilter/nf_nat_ipv4.ko/a09fe3eb3147dafa4e3b31dbd6257e4d696bdc92
|
||||
*/
|
||||
ch = strrchr(bf, '/');
|
||||
if (!ch)
|
||||
goto err;
|
||||
if (ch - 3 < bf)
|
||||
goto err;
|
||||
|
||||
return strncmp(".ko", ch - 3, 3) == 0;
|
||||
err:
|
||||
/*
|
||||
* If dso__build_id_filename work, get id_name again,
|
||||
* because id_name points to bf and is broken.
|
||||
*/
|
||||
if (id_name)
|
||||
id_name = dso__build_id_filename(dso, bf, size);
|
||||
pr_err("Invalid build id: %s\n", id_name ? :
|
||||
dso->long_name ? :
|
||||
dso->short_name ? :
|
||||
"[unknown]");
|
||||
return false;
|
||||
}
|
||||
|
||||
#define dsos__for_each_with_build_id(pos, head) \
|
||||
list_for_each_entry(pos, head, node) \
|
||||
if (!pos->has_build_id) \
|
||||
|
@ -16,6 +16,7 @@ int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id);
|
||||
int filename__sprintf_build_id(const char *pathname, char *sbuild_id);
|
||||
|
||||
char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size);
|
||||
bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size);
|
||||
|
||||
int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
|
||||
struct perf_sample *sample, struct perf_evsel *evsel,
|
||||
|
@ -1529,6 +1529,10 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
|
||||
if (!runtime_ss && syms_ss)
|
||||
runtime_ss = syms_ss;
|
||||
|
||||
if (syms_ss && syms_ss->type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
|
||||
if (dso__build_id_is_kmod(dso, name, PATH_MAX))
|
||||
kmod = true;
|
||||
|
||||
if (syms_ss)
|
||||
ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod);
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user