可以无限期地访问文件映射内存

问题描述:

是否有可能无限延长对内存位置的读取(并且允许另一个线程允许在任意超时后完成读取)?可以无限期地访问文件映射内存

例如,阻止套接字,我们可以得到一个进程使用read系统调用时停止:

fd = socket(AF_UNIX, SOCK_DGRAM, 0); 
read(fd, buffer, 256); 

通常我们不能mmap插座,但我基本上是一样的东西发生直接访问内存时:

int x = *(int *)map; 

我知道的技术,使内存访问需要更长的时间,比如访问之前使用madvise页出内存,但我找得到这个持续的方法无限期。

我已经考虑在文件上使用mmap,然后“锁定”该文件,但找不到适当的接口。系统调用似乎不能以这种方式工作。

具体来说,我对FreeBSD x86-64体系结构感兴趣,但对其他类Unix系统(如Linux)以及其他体系结构的答案也将不胜感激。

+0

如果你想“阻止”内存访问,你可以尝试mmap()在NFS挂载文件,并在这个内存上执行一些真正的随机访问。 – wildplasser

+0

如果该文件位于自定义['FUSE' mount](https://en.wikipedia.org/wiki/Filesystem_in_Userspace)上,您可以获得任意的行为。 –

您可以使用mprotect(..., PROT_NONE)将包含map的页面标记为不可访问。当您尝试访问它时,会发生页面错误,并且会引发SIGSEGV

您可以安装SIGSEGV的处理程序,声明时带有额外的siginfo_t参数。查看该结构的si_addr成员以检查错误地址是否匹配map;这使您可以区分来自其他代码中的实际错误(例如NULL解除引用)的其他错误对此地址的访问。如果是这样,那么信号处理程序可以等待直到被另一个线程告知继续。准备就绪后,请拨mprotectPROT_READ(或PROT_WRITE视情况而定)并从信号处理程序返回;错误指令重新启动并继续执行。

这是一个相当丑陋的黑客攻击,我建议你好好看看为什么你认为你需要这样做。你的问题似乎可能是XY problem

+0

我已经实现了你的建议,它适用于userland访问(EG:'*(int *)buffer = 0;'),但它不会冻结来自内核的写入,这是我的最终目标(EG:'getcontext ((ucontext_t *)buffer);')。 – CHRIS

+0

@CHRIS:内核模式是一种完全不同的动物。如果那是你的目标,我希望你这样说。事实上,你应该问一个新的问题。 –

+0

我会接受你的答案,因为它适用于我最初描述的问题。谢谢。 – CHRIS