性能:内核模块符号未显示在分析中

Posted

技术标签:

【中文标题】性能:内核模块符号未显示在分析中【英文标题】:Perf: kernel module symbols not showing up in profiling 【发布时间】:2017-06-02 10:21:13 【问题描述】:

加载和运行内核模块,然后通过 perf 进行分析。

$perf record -a -g --call-graph dwarf sleep 30' $perf report

性能报告中没有我的内核模块的符号。 虽然符号出现在/proc/kallsyms. 该模块也不存在于perf buildid-list 正如this 的回答所说,要使模块成为内核模块,我试过但没有帮助。 可能导致这种情况的原因是什么?

【问题讨论】:

您的模块是长时间计算某些东西还是调用计算时间长的东西?如果模块函数或某些通过模块函数解析为调用的函数中没有分析示例,则模块将不会在性能报告中显示任何内容。 我的函数确实运行了足够长的时间。我怎么知道?因为我从用户空间程序中运行了相同的函数,并在分析报告中看到了它的符号,并且占用了相当多的 CPU 时间。我想知道 perf 是否有某种方式无法访问我的外部内核模块的符号? 在获取导致问题的分析报告时是否会出现以下警告? no symbols found in /sbin/dhclient, maybe install a debug package? no symbols found in /bin/kmod, maybe install a debug package? Failed to open [thrUserCtrl], continuing without symbols no symbols found in /usr/sbin/dnsmasq, maybe install a debug package? 萨蒂,那么,模块本身有很长的功能吗?每个 dso 都有没有调试符号的消息,大多数是用户空间程序,但是“thrUserCtrl”是你的模块吗? Perf 找不到它,它是否安装到 /lib/modules/`uname -r`/extra (wiki.centos.org/HowTos/BuildingKernelModules) 中?你的内核版本是什么 (uname -a?) 回答您的问题:是的,模块本身有很长的功能。是的 'thrUserCtrl' 是我的模块。不,我还没有安装我in /lib/modules/uname -r/extra 。内核版本是 - 3.13.0-32-generic。 【参考方案1】:

消息Failed to open [thrUserCtrl], continuing without symbols 听起来好像 perf 无法找到您的模块。尝试将其安装到

/lib/modules/`uname -r`/extra

https://wiki.centos.org/HowTos/BuildingKernelModules中所说的目录:

6. In this example, the file cifs.ko has just been created. 
 As root, copy the .ko file to the /lib/modules/<kernel-version>/extra/
 directory.
   [root@host linux-2.6.18.i686]# cp fs/cifs/cifs.ko /lib/modules/`uname -r`/extra

(更改/lib/modules中的文件后不要忘记depmod -a命令)

此消息生成于map__load:http://elixir.free-electrons.com/linux/v4.11/source/tools/perf/util/map.c#L284

int map__load(struct map *map)

    const char *name = map->dso->long_name;
    int nr;
    ...
    nr = dso__load(map->dso, map);
    if (nr < 0) 
        if (map->dso->has_build_id) 
         ...
         else
            pr_warning("Failed to open %s", name);

        pr_warning(", continuing without symbols\n");
        return -1;

dso__load 函数返回错误时。

【讨论】:

尝试使用--kallsyms= 选项将kallsyms 文件指定为perf report 命令。 正如它所说的将模块安装在'/lib/modules/uname -r/extra'不是使模块成为内核的一部分吗? perf 是否可以通过指定我的模块的 .ko 文件或类似文件的路径来分析使用 insmod 加载的模块? 我将模块复制到'/lib/modules/uname -r/extra' 和 modprobe 以加载它。现在我可以看到我的模块和它的***函数(传递给线程的函数),但性能报告中仍然没有其他函数(由线程函数调用的函数)符号。 很高兴,您的模块的内部函数可能被内联到***函数中(重新编译时禁用内联 -fno-inline 或没有优化 -O0 以查看所有内容)。现在您可以看到模块的功能和解决的问题。不,复制到 extra 并不是使模块成为内核的一部分。还不知道 perf 如何搜索模块,但insmod 可能在任何地方都没有记录完整路径,或者它可能在较新的内核中工作(3.13 在 dso__load 中的模块支持较少,只有 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE 在 elixir.free-electrons.com/linux/v3.13/source/tools/perf/util/… 中) .

以上是关于性能:内核模块符号未显示在分析中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux 内核模块中找到合适的 DWARF 符号作为地址?

模块机制

内核符号导出

访问未通过 EXPORT_SYMBOL* 导出的 Linux 内核符号

Insmod模块加载过程分析

内核模块未加载(但insmod返回0)