Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux中的mprotect_Linux_Copy On Write_Mprotect - Fatal编程技术网

linux中的mprotect

linux中的mprotect,linux,copy-on-write,mprotect,Linux,Copy On Write,Mprotect,如果我mprotect一个没有PROT\u的段,如果SIGSEGV由于sigaction和sa\u sigaction处理的写入而发生,我们将能够使用sigainfo\u t的si\u addr>找到故障发生的地址。但是,有没有办法找到要写入的数据和数据长度 我之所以尝试这样做,是因为我正在为我的项目尝试一种写时拷贝机制 您找不到进程试图写入的数据,询问其大小也没有意义。如果你能得到数据,那就意味着内核已经在某处复制了它 您在整个页面上获得一个SIGSEGV。也就是说,无论进程写入的数据是什么,

如果我
mprotect
一个没有PROT\u的段,如果
SIGSEGV
由于
sigaction
sa\u sigaction
处理的写入而发生,我们将能够使用
sigainfo\u t
si\u addr>找到故障发生的地址。但是,有没有办法找到要写入的数据和数据长度


我之所以尝试这样做,是因为我正在为我的项目尝试一种写时拷贝机制

您找不到进程试图写入的数据,询问其大小也没有意义。如果你能得到数据,那就意味着内核已经在某处复制了它

您在整个页面上获得一个
SIGSEGV
。也就是说,无论进程写入的数据是什么,每页都会出现一个错误——第一次尝试写入一个字节时。因此,您需要做的就是:

  • 跟踪页面状态
  • 根据需要增加权限

    • 您找不到进程试图写入的数据,询问其大小也没有意义。如果你能得到数据,那就意味着内核已经在某处复制了它

      您在整个页面上获得一个
      SIGSEGV
      。也就是说,无论进程写入的数据是什么,每页都会出现一个错误——第一次尝试写入一个字节时。因此,您需要做的就是:

      • 跟踪页面状态
      • 根据需要增加权限

        • 内核不知道,因此无法告诉您。但是如果你想的话,你可以试试看。您拥有堆栈上出现故障的代码地址,因此您可以在那里反汇编代码以尝试找出它。没有其他方法可以知道(如果你不清楚原因,请想一想)。该指令出现故障,因为它触及了受保护的页,除非您分析汇编代码,否则这就是已知的全部

          如果你不能通过只知道出现错误的页面来判断你在处理什么对象,我强烈建议你重新考虑改变你的设计。(
          posix_memalign
          ,也许吧?)

          更新:不要忘记,您需要在每个上下文切换上调用一个钩子。您可能需要在每个钩子上复制页面。例如:

        • 上下文A使用CoW语义访问页面Q。上下文A以只读方式访问该页

        • 上下文B使用CoW语义访问页面Q。上下文B以只读方式访问该页

        • 上下文A去修改页面,我们为上下文B创建一个副本。上下文A现在拥有对页面的写访问权并修改它

        • 我们从上下文A切换到上下文B。此时,您必须切换为上下文B制作的页面副本


        • 请注意,另一种解决方法是让上下文对映射和锁定页面进行特定调用。如果您允许一个上下文在一个上下文开关上保存映射,那么这是行不通的——至少,如果没有大量额外的工作,这是行不通的。

          内核不知道,所以它不能告诉您。但是如果你想的话,你可以试试看。您拥有堆栈上出现故障的代码地址,因此您可以在那里反汇编代码以尝试找出它。没有其他方法可以知道(如果你不清楚原因,请想一想)。该指令出现故障,因为它触及了受保护的页,除非您分析汇编代码,否则这就是已知的全部

          如果你不能通过只知道出现错误的页面来判断你在处理什么对象,我强烈建议你重新考虑改变你的设计。(
          posix_memalign
          ,也许吧?)

          更新:不要忘记,您需要在每个上下文切换上调用一个钩子。您可能需要在每个钩子上复制页面。例如:

        • 上下文A使用CoW语义访问页面Q。上下文A以只读方式访问该页

        • 上下文B使用CoW语义访问页面Q。上下文B以只读方式访问该页

        • 上下文A去修改页面,我们为上下文B创建一个副本。上下文A现在拥有对页面的写访问权并修改它

        • 我们从上下文A切换到上下文B。此时,您必须切换为上下文B制作的页面副本

        • 请注意,另一种解决方法是让上下文对映射和锁定页面进行特定调用。如果允许上下文在上下文开关之间保存映射,那么这是行不通的——至少,如果没有大量额外的工作,这是行不通的。

          使用mprotect()时,您知道要保护的内存段的起始地址和长度。您需要将该信息存储在某个位置,以便以后使用

          一旦您保护了内存段,如果您以违反保护的方式访问它,您将得到SIGSEGV信号。在信号处理程序中,您将获得指向siginfo\u t的指针。这将为您提供所需的信息。si\u addr提供了导致非法访问的指令的地址,而si\ptr为您提供了非法访问的地址。然后将si_ptr与受保护的内存段进行比较,直到找到它所属的内存段,这就是“写时复制”需要复制的内存段。。。完成后,需要调用setcontext()或siglongjmp()之类的函数,以便从已知位置继续运行

          我希望这能有所帮助。

          使用mprotect()时,您知道要保护的内存段的起始地址和长度。您需要将该信息存储在某个位置,以便以后使用

          一旦您保护了内存段,如果您以违反保护的方式访问它,您将得到SIGSEGV信号。在信号处理程序中,您将获得指向siginfo\u t的指针。这将为您提供所需的信息。si_addr为您提供导致非法访问的指令的地址,si_ptr为您提供被访问的地址