我想知道是否有一种方法可以在Linux 进程的地址空间(从进程本身内部,通过 mprotect()
)写保护每一页。通过“每一页”,我的意思是每个页面的进程的地址空间可能会被一个普通的 程序在用户模式下运行 - 所以程序文本,常量,全局变量和堆 - - 但我会很满意常量,全局变量和堆。我不想写保护堆栈 - 似乎是一个坏主意。我可以在Linux进程的地址空间中写保护每个页面吗?
一个问题是,我不知道从哪里开始写保护 内存。查看/proc/pid/maps
,其中显示了用于给定pid的内存 的各个部分,但他们似乎始于具有程序文本的地址 0x08048000
。 (在Linux中,据我所知, 一个进程的内存是用底部的 底部的程序文本进行布局的,然后是常量,然后是全局变量,然后是堆,然后是 一个大小不同的空白空间堆的大小或者堆栈的大小,然后堆栈从内存顶部向下增长,在 虚拟地址0xffffffff
。)有一种方法可以告诉堆的顶端是哪个堆(是通过调用sbrk(0)
,它只是返回一个指向 当前“中断”的指针,即堆顶部),但不是真正的方法来告诉堆的开始位置。
如果我试图保护从0x08048000
到中断的所有页面,我最终会得到mprotect: Cannot allocate memory
错误。我不知道为什么mprotect
会是 无论如何分配内存 - 谷歌是不是很有帮助。有任何想法吗?
顺便说一句,我想这样做的原因是因为我希望创建一个在程序的运行过程中写入的所有页面的 列表, ,我能想到的这样做的方法是对所有页面进行写保护,让任何尝试写入导致写入错误,然后执行写入 错误处理程序,该页面将页面添加到列表中,然后删除写入 保护。我想我知道如何实现处理程序,如果只有我能 找出哪些页面要保护以及如何去做。
谢谢!
我其实已经有了代码,完全符合你想要做的事情。你的想法会起作用,但是你无法保护你的“这些页面被写入”列表所在的页面,或者你的SEGV处理程序将导致SEGV! – Borealid 2010-08-10 00:36:08
@Borealid,谢谢,现在我正试图解决这个问题(我已经有了segfault处理程序,并且/ proc/self/maps解析现在可以工作)。如何避免保护包含该列表的页面?在堆栈上分配列表可行,但我没有看到任何方式将它传递给处理程序。另外,我可以将它作为全局分配,但我想使用比定长数组(比如STL容器)更出色的数据结构,并且我可能并不总是知道我写入的列表位于何处在记忆中。 – 2010-08-11 00:13:45
@borealid:你说你有这样做的代码 - 你介意分享你的代码吗?我是新来的,而且我找不到直接与您联系的方式(反向频道)。我正在努力完成Linsey正在做的事情,所以任何代码示例都会非常有帮助。 – 2010-11-21 17:37:41