用户定义的页面错误和异常处理程序
我想了解我们是否可以在内核 / 用户模式中添加页面故障处理程序 / 异常处理程序以及在将控制权交还给内核之前处理我们引发的错误。 这里的任务不是修改现有的内核代码(do_page_fault fn),而是添加一个用户定义的处理程序,当触发页面错误或异常时将查找该
处理程序人们可以找到诸如“ >kprobe”,它在指令中提供钩子,但看起来这不能满足我的目的。
如果有人能帮助我理解这一点或指出好的参考资料,那就太好了。
I am trying to understand if we can add our page fault handlers / exception handlers in kernel / user mode and handle the fault we induced before giving the control back to the kernel.
The task here will be not modifying the existing kernel code (do_page_fault fn) but add a user defined handler which will be looked up when a page fault or and exception is triggered
One could find tools like "kprobe" which provide hooks at instruction, but looks like this will not serve my purpose.
Will be great if somebody can help me understand this or point to good references.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在用户空间中,您可以为 SIGSEGV 定义信号处理程序,因此每当进行无效内存访问时都会调用您自己的函数。与 mprotect() 结合使用时,程序可以从用户空间管理自己的虚拟内存。
但是,我的印象是您正在寻找一种方法来拦截所有页面错误(主要、次要和无效)并调用任意内核函数作为响应。我不知道有什么干净的方法可以做到这一点。当我自己的研究项目需要此功能时,我最终将代码添加到
do_page_fault()
中。它对我来说效果很好,但它是一个黑客。如果有人知道一种干净的方法来做到这一点(即可以由普通内核上的模块使用),我会非常感兴趣。From user space, you can define a signal handler for SIGSEGV, so your own function will be invoked whenever an invalid memory access is made. When combined with
mprotect()
, this lets a program manage its own virtual memory, all from user-space.However, I get the impression that you're looking for a way to intercept all page faults (major, minor, and invalid) and invoke an arbitrary kernel function in response. I don't know a clean way to do this. When I needed this functionality in my own research projects, I ended up adding code to
do_page_fault()
. It works fine for me, but it's a hack. I would be very interested if someone knew of a clean way to do this (i.e., that could be used by a module on a vanilla kernel).如果您不想改变内核处理这些错误的方式,只需在之前添加您的错误,那么
kprobes
将满足您的目的。它们有点难以处理,因为您在包含寄存器的结构中和堆栈上获取被探测函数的参数,并且您必须知道编译器将它们中的每个参数到底放在哪里。但是,如果您需要它来实现特定功能(在创建探测器期间已知),那么您可以使用jprobes
(这里是一个关于如何使用两者的很好的例子),它需要使用与被探测的参数完全相同的参数进行探测的函数(因此没有损坏在寄存器/堆栈中)。您可以动态加载内核模块并在选定的函数上安装
jprobes
,而无需修改内核。If you don't won't to change the way kernel handles these fault and just add yours before, then
kprobes
will server your purpose. They are a little difficult to handle, because you get arguments of probed functions in structure containing registers and on stack and you have to know, where exactly did compiler put each of them. BUT, if you need it for specific functions (known during creation of probes), then you can usejprobes
(here is a nice example on how to use both), which require functions for probing with exactly same arguments as probed one (so no mangling in registers/stack).You can dynamically load a kernel module and install
jprobes
on chosen functions without having to modify your kernel.您可以使用 gnu libsegsev 安装用户级寻呼机。我没有使用过它,但它似乎正是您正在寻找的。
You want can install a user-level pager with gnu libsegsev. I haven't used it, but it seems to be just what you are looking for.
我认为这是不可能的 - 首先,页面错误处理程序是一个复杂的函数,需要直接访问虚拟内存子系统结构。
其次,想象这不会是一个问题,但是为了在用户空间中编写页面错误处理程序,您应该能够捕获默认情况下强制传输到内核空间的错误,因此至少您应该防止这种情况发生。
为此,您需要一个主管来跟踪所有内存访问,但您不能保证主管代码已经映射并存在于内存中。
I do not think it would be possible - first of all, the page fault handler is a complex function which need direct access to virtual memory subsystem structures.
Secondly, imagine it would not be an issue, yet in order to write a page fault handler in user space you should be able to capture a fault which is by default a force transfer to kernel space, so at least you should prevent this to happen.
To this end you would need a supervisor to keep track of all memory access, but you cannot guarantee that supervisor code was already mapped and present in memory.