C 字节级写访问保护?

C 字节级写访问保护?,c,mprotect,C,Mprotect,保护页面进行读和/或写访问是可能的,因为页面表条目中有一些位可以在内核级别打开和关闭。有没有一种方法可以保护内存的某个区域不被写访问,比如说在C结构中有某些变量需要被写保护,对它们的任何写访问都会触发SEGFULT和核心转储。它有点像mprotect()的缩小功能,因为它在页面级别工作,在用户空间的字节级别上有类似的机制 谢谢,Kapil Upadhayay。不,没有这样的设施。如果需要每个数据对象的保护,则必须为每个对象至少分配一页(使用mmap)。如果您还想对超出对象末尾的访问(对于数组)提

保护页面进行读和/或写访问是可能的,因为页面表条目中有一些位可以在内核级别打开和关闭。有没有一种方法可以保护内存的某个区域不被写访问,比如说在C结构中有某些变量需要被写保护,对它们的任何写访问都会触发SEGFULT和核心转储。它有点像mprotect()的缩小功能,因为它在页面级别工作,在用户空间的字节级别上有类似的机制


谢谢,Kapil Upadhayay。

不,没有这样的设施。如果需要每个数据对象的保护,则必须为每个对象至少分配一页(使用
mmap
)。如果您还想对超出对象末尾的访问(对于数组)提供一些保护,您可以分配至少一个超出需要的页面,对齐对象使其正好在页面边界处结束,并使用
mprotect
保护您分配的一个或多个额外页面


当然,这种方法会导致程序非常缓慢,浪费大量资源。除了作为一种调试技术之外,它可能是不可行的,valgrind可以更有效地满足这一需求,而无需修改您的程序……

不,没有这样的工具。如果需要每个数据对象的保护,则必须为每个对象至少分配一页(使用
mmap
)。如果您还想对超出对象末尾的访问(对于数组)提供一些保护,您可以分配至少一个超出需要的页面,对齐对象使其正好在页面边界处结束,并使用
mprotect
保护您分配的一个或多个额外页面


当然,这种方法会导致程序非常缓慢,浪费大量资源。除了作为一种调试技术之外,它可能是不可行的,valgrind可以更有效地满足这一需求,而无需修改您的程序……

一种方法,尽管速度非常慢,但就是保护对象所在的整个页面。每当发生对该页的写访问时,就会调用无效页访问的自定义处理程序,并通过快速取消对该页的保护、写入数据然后再次保护该页来解决这种情况

这适用于单线程程序,但我不确定如何处理多线程程序


这个想法可能并不新鲜,因此您可能可以找到一些信息,甚至可以找到它的现成实现。

一种方法,尽管速度非常慢,但就是保护对象所在的整个页面。每当发生对该页的写访问时,就会调用无效页访问的自定义处理程序,并通过快速取消对该页的保护、写入数据然后再次保护该页来解决这种情况

这适用于单线程程序,但我不确定如何处理多线程程序


这种想法可能并不新鲜,因此您可以找到一些信息,甚至可以找到它的现成实现。

如果您想编写可移植代码,这是正确的,但gdb几乎在任何地方都实现了内存观察点,因此毫无疑问,它使用的一些技巧将有助于具体实现。如果是字级或更大的,而不是字节级,你可以大致按照罗兰描述的那样做:捕捉条件,检查地址是否是你要查找的地址。我认为它可以保护整个页面,处理错误,并且只在写操作与观察点匹配时才停止执行。不过我可能弄错了;我认为一些硬件有少量的特定地址可以安装为监视点,但这绝对不是任何大规模的操作。如果它不能做到这一点,那么它也可能是一种性能优化:-)我认为重要的一点是,你不必为每个对象分配一个或多个页面,在硬件级保护完成后,您可以实现自己的保护。如果您想编写可移植代码,这是正确的,但gdb几乎在任何地方都实现了内存观察点,因此毫无疑问,它使用了一些技巧来帮助特定的实现。如果是字级或更大的,而不是字节级,你可以大致按照罗兰描述的那样做:捕捉条件,检查地址是否是你要查找的地址。我认为它可以保护整个页面,处理错误,并且只在写操作与观察点匹配时才停止执行。不过我可能弄错了;我认为一些硬件有少量的特定地址可以安装为监视点,但这绝对不是任何大规模的操作。如果它不能做到这一点,那么它也可能是一种性能优化:-)我认为重要的一点是,你不必为每个对象分配一个或多个页面,在硬件级保护完成后,您可以实施自己的保护。对于多线程程序,如果您的保护处理程序是一个单独的进程(例如使用
ptrace
),您可以停止整个进程(通过
SIGSTOP
或某些
ptrace
特定方法)这样你就不用担心比赛了。如果它在同一个进程中,您可以使用一个特殊的信号来捕获信号处理程序中的所有线程,并将它们保持在那里,直到处理程序完成。无论哪种方式,它都会有糟糕的性能。对于多线程程序——如果您的保护处理程序是一个单独的进程(例如使用
ptrace
),您只需停止整个进程(通过
SIGSTOP
或某些
ptrace
特定的方法),然后您就不必担心争用。如果它在同一个进程中,您可以使用一个特殊的信号来捕获信号处理程序中的所有线程,并使它们保持不变