Operating system 操作系统内部到底发生了什么导致分段错误

Operating system 操作系统内部到底发生了什么导致分段错误,operating-system,segmentation-fault,Operating System,Segmentation Fault,我读了很多关于虚拟地址和分页的文章。 让我先告诉你们我所理解的。当一个进程想要执行某件事情时,它会尝试将数据从硬盘加载到内存中。为此,它使用一个虚拟地址。因此,我们的MMU验证虚拟地址,查看TLB以找到相应的物理页,如果找不到,则查看反向页表,最后查看页表。如果找不到条目,则生成页错误,所有页交换都完成,所有表都将更新。 正如我读到的,所有进程都有不同的页表和相同的虚拟地址。因此,如果我尝试访问一个数组元素a[1000],它被定义为int a[100],我肯定会得到一个分段错误,因为该指令可能试

我读了很多关于虚拟地址和分页的文章。 让我先告诉你们我所理解的。当一个进程想要执行某件事情时,它会尝试将数据从硬盘加载到内存中。为此,它使用一个虚拟地址。因此,我们的MMU验证虚拟地址,查看TLB以找到相应的物理页,如果找不到,则查看反向页表,最后查看页表。如果找不到条目,则生成页错误,所有页交换都完成,所有表都将更新。 正如我读到的,所有进程都有不同的页表和相同的虚拟地址。因此,如果我尝试访问一个数组元素a[1000],它被定义为int a[100],我肯定会得到一个分段错误,因为该指令可能试图访问一个不属于它的内存。但是操作系统如何通过使用虚拟地址和物理页面的概念来知道[1000]不属于正在运行的进程。是我遗漏了什么,还是我的全部理解都错了

我知道,如果进程试图访问只读或sup true内存段,我们可以说内存访问是非法的

最后一个棘手的问题是,操作系统如何决定将哪些内存分配给哪个进程,以及如何决定这种内存访问是非法的

这个链接没有多大帮助


非常感谢大家的支持:)

实际上Linux内核中的每个进程都有一个定义良好的结构,称为task_struct,它存储了有关相应进程的所有信息,如父进程、PID、子进程、地址空间、挂起信号、,与之关联的线程等。现在,地址空间条目在执行进程时告诉内核该进程的合法地址空间。每个进程从创建之初就有自己的地址空间由内核分配给它。因此,当一个正在执行的进程试图访问其合法内存之外的空间时,会生成一个错误(在
Unix/Linux
中称为分段错误),并通过内核向其发送信号来终止该进程。在操作系统中实现内存保护非常重要。

在x86上,linux使用分段和分页的组合,因此程序生成的地址首先查找相应的段基址和限制寄存器值。这将给出虚拟地址,然后使用页表转换虚拟地址。当您试图访问尚未分配的内存时,访问的页面超出了限制寄存器允许的范围,因此产生了分段错误。

非常感谢您的输入。但是在这里,我们所说的地址空间是什么意思?我们指的是虚拟地址空间吗?你们能告诉我更多一些关于地址空间和内存分配的信息吗?每个人都说分页很好,因为它提供了内存隔离,这不是真的吗?是的,看看今天的Os 2,东西都是虚拟化的:处理器和内存。因此,对于当前的应用程序来说,将其视为任何内存地址空间并没有什么复杂的事情。就分页而言,它只是从内核大小来调整内存的一种方式。它有助于为不同的应用程序(如DMA、正常执行)组织内存。实际上,由于内核在kerenl模式下运行,因此它已经预先验证了对硬件的访问,因此需要某种机制来保护在内核空间中运行的用户空间进程(如执行系统调用)访问任何其他内核进程地址空间。但交易是针对所有进程,32位处理器的虚拟地址从0x08048000开始,64位处理器的虚拟地址从0x400000开始,所以所有进程的虚拟地址都必须相同,对吗?在内核空间中运行的处理方法是将虚拟地址空间划分为内核空间和用户空间,并且不允许进程访问任何krenal空间虚拟地址。但是这两个进程之间的保护又如何呢?因为对于所有进程,虚拟地址都是相同的,操作系统如何使一个进程不访问另一个进程的内存?+1有关进程的虚拟映射存储位置的一些好信息。