linux-kernel - 如何阅读使用 LKM 中的 perf 接口停用的指令?
问题描述
如何从内核空间内部读取 PMU?
对于分析任务,我需要从内核内部读取 PMU 提供的退役指令。perf_event_open系统调用似乎提供了这种能力。在我的源代码中
#include <linux/syscalls.h>
为 perf_event_attr 结构设置我的参数并调用sys_perf_event_open()。提到的标头包含函数声明。检查“/proc/kallsyms”时,确认存在名称为sys_perf_event_open的系统调用。该符号在全球范围内可用T表示:
ffffffff8113fe70 T sys_perf_event_open
因此,据我所知,一切都应该有效。
尽管如此,在编译或插入 LKM 时,我收到一个警告/错误,即sys_perf_event_open不存在。
WARNING: "sys_perf_event_open" [/home/vagrant/mods/lkm_read_pmu/read_pmu.ko] undefined!
我需要做什么才能获得那些已停用的指令计数器?
解决方案
该/proc/kallsyms
文件显示了源代码中定义的所有内核符号。对,大写的 T 表示内核二进制文本部分中的全局符号,但这里的“全局”的含义是根据 C 语言。也就是说,它可以在内核本身的其他文件中使用。您不能仅仅因为它是全局的而从内核模块调用内核函数。
内核模块只能使用EXPORT_SYMBOL
在内核源代码中导出的内核符号。从内核 2.6.0 开始,没有任何系统调用被导出,因此您不能从内核模块调用它们中的任何一个,包括sys_perf_event_open
. 系统调用实际上是为从用户空间调用而设计的。这一切意味着您不能在内核模块中使用 perf_event 子系统。
也就是说,我认为您可以修改内核以添加EXPORT_SYMBOL
到sys_perf_event_open
. 这将使它成为一个导出符号,这意味着它可以从内核模块中使用。
推荐阅读
- rest - 此 python servicenow 脚本的 Perl 版本发布文件
- php - 显示来自查询字符串的图像
- google-apps-script - 谷歌脚本自动隐藏空单元格,应该刷新吗?
- javascript - 如何从 Mapbox GL JS 中的 geojson 源获取独特的特征属性?
- java - 如何生成由在 websphere 9 上运行的应用程序分隔的日志文件?我使用 java.util.logging 生成日志
- javascript - Json 确实返回 -1 而不是存储过程中的值
- data-warehouse - 我可以使用许多事实表吗?我的 DW 有很多事实表,针对不同的产品
- c# - 实例化游戏对象功能不起作用
- mongodb - 在MongoDB中满足条件时的总和值
- .net-core - 在 .NET Core 2.2 SignalR Hub 上作为 EXE 发布,不能在自托管上工作,但在 Visual Studio 中工作