Professional Documents
Culture Documents
第7章 异常控制流
第7章 异常控制流
令存放的顺序执行,以及跳转到转移类指令指出
的转移目标地址执行
异常的基本概念
程序执行的顺序
异常控制流:程序正常执行过程中,CPU因为遇
异常:由CPU内部产生的意外事件称为异常,也 到内部异常实践或者外部中断时间而打断原来程
称为内中断 序的执行,转去执行操作系统提供的针对这些特
殊时间的处理程序的意外控制流
中断:从CPU外部通过中断请求引脚INTR和NMI
基本概念
向CPU发出的中断请求,称为外中断
Intel提供的定义:处理器提供了异常和中断这两 程序:代码和数据的集合,是一个机器指令序
种打断程序正常执行的机制,中断是一种典型的 列,程序是一个静态的概念
由I/O设备触发的、与当前正在执行的指令无关的
异步事件,而异常是处理器执行一条指令时,由 进程:程序的一次运行过程,是一个具有一定独
处理器在其内部检测到的、与正在执行的指令相 立功能的程序关于某个数据集合的一次运行活动
关的同步事件
计算机处理的所有任务实际上是由进程完成的
当CPU执行当前程序或任务时检测到一个异常时
间,或者在执行完指令后发现有一个中断请求信 每个应用程序在系统中运行时都有属于自己的存
号,那么CPU后打断当前用户进程,然后转移到 储空间,用来存储自己的程序代码和数据,包括
相应的异常或者中断处理程序去执行 只读区、可读可写数据区、动态的堆区和栈区等
如果异常或中断处理程序能够解决问题,则在异 进程是操作系统堆处理器中程序运行过程的一种
常或中断处理程序的最后,CPU通过执行异常或 抽象,进程有自己的生命周期,它由任务的启动
中断返回指令回到被打断的用户进程继续执行 异常和中断处理的大致过程 程序和进程的概念
创建,随着任务的完成而消亡,它所占用的资源
也随着进程的终止而释放
如果异常处理程序发现这是一个致命错误,那么
终止用户进程 进程描述符:Linux中用于描述进程的结构,包含
了进程的所有信息
通常情况下,对于异常和中断事件的具体处理过
程全部通过操作系统软件来完成 任务列表:一个双向循环链表,描述系统中的所
有进程,任务列表的每一个元素是一个进程描述
异常处理程序:处理异常事件的程序 符
中断服务程序:处理中断事件的程序 进程简化了编程、编译、链接、共享和加载的过
异常或中断处理程序:异常处理程序和中断服务
程
程序的统称
独立的逻辑控制流:程序员以为自己的程序在执
行的过程中独占的处理器
故障是指令在执行的过程中,CPU检测到的一类
进程为应用程序提供的抽象
与指令相关的意外事件
虚拟地址空间:程序员以为自己的程序在执行过
程中独占存储器
对于无法通过异常处理程序恢复的故障,通常异
常处理程序在屏幕上显示一个对话框告知发生了
故障 逻辑控制流:进程的指令执行过程中,形成的执
某种故障,然后调用abort例程,终止发生故障的
行指令的地址序列
当前例程
物理控制流:由多个逻辑控制流组成,因为多个
段故障:Linux中对于不可恢复的访存故障例如地
进程之间会轮流使用处理器
址越界和访问越权,都成为段故障
一个进程的逻辑控制流总是确定的,不管中间是
陷阱是预先安排的异常事件,当执行到陷阱指令
否被其他的进程打断,也不管被打断几次和在哪
时,CPU调出特定的程序进行相应的处理,处理 进程的逻辑控制流
第 章 异常控制流 里被打断,这样就可以保证一个进程不管怎么被
结束后返回到陷阱指令的下一条指令执行
打断它的行为总是一致的
7
系统调用:陷阱在用户程序和内核之间提供一个
并发:不同进程的逻辑控制流在时间上交错或重
像过程调用一样的接口,这个接口称为系统调
叠的情况
用,用户进程通过这个接口可以方便的使用操作
系统提供的一些服务
异常的分类 异常和中断
陷阱 并行:两个逻辑控制流同时执行
系统调用号:操作系统对能提供的服务进行的编
时间片:连续执行同一个进程的时间段
号,每个服务功能通过一个对应的系统调用服务
例程提供,例如folk(),read(),execve()和
上下文切换:操作系统通过处理器调度让处理器
轮流执行多个进程,实现不同继承中指令交替执
mmap()
利用陷阱可以实现程序调试功能,包括设置断点 行的机制
和单步跟踪 进程的上下文:进程的物理实体和支持进程运行
如果在执行指令过程中发生了严重的错误,例如
的环境
控制器出现问题,访问DRAM或SRAM时发生校
终止 用户级上下文:由用户进程的程序块、数据块、
验错等,则程序无法执行,只好终止发生问题的
运行时的堆和用户栈等组成的用户空间信息
进程
通过可屏蔽中断请求线INTR向CPU进行请求的中 系统级上下文:由进程标识信息、进程现场信
断,主要来自I/O设备的中断请求 进程的上下文切换
息、进程控制信息和系统内核栈组成的内核空间
信息
可屏蔽中断
CPU可以通过在中断控制器中设置相应的屏蔽字
来屏蔽或者不屏蔽它,如果一个I/O设备的中断请 进程的虚拟地址空间:用户级上下文和系统级上
求被屏蔽,则它的中断请求信号不会被送到CPU 下文共同构成的存储器的映像
中断的分类 寄存器上下文:处理器中各个寄存器的内容
非常紧急的硬件故障,通过专门的不可屏蔽中断
请求线NMI向CPU发出的请求
将当前处理器的寄存器上下文保存到当前进程的
这类中断请求信号一旦产生,任何情况下它都不 系统级上下文的现场信息中
可以被屏蔽,因此一定会被送到CPU,以便让 不可屏蔽中断
CPU快速处理这类紧急事件 将新进程上下文中的现场信息作为新的寄存器上
上下文切换的过程
下文恢复到处理器的各个寄存器中
通常这种情况下中断服务程序会尽快保存系统重
要信息,然后在屏幕上现实相应的消息或者直接 将控制转移到新的进程执行,这里一个重要的上
重启系统 下文信息就是PC的值
CPU对异常和中断的相应过程可以分为三个步 存储器映射:将进程的虚拟地址空间中的一个区
骤:保护断点和程序状态、关中断、识别异常和 域与硬盘上的一个对象建立关联,以初始化一个
中断事件并转到相应处理程序 vm_area_struct数据结构中的信息
断点与异常状态有关,为了程序在处理完异常以 mmap函数进行存储器映射,创建某进程虚拟地
后能够正常执行,数据通路必须能够正确计算断 址空间中的一个区域,生成一个vm_area_struct
点的地址 结构
保护断点和程序状态 PROT_EXE:区域内页面由可执行的指令组成
为了能够支持异常或者中断的嵌套处理,大多数
处理器将断点保存在栈中,如果硬件不支持嵌套
处理,那么也可以将断点保存在寄存器中,访问 PROT_READ:区域内页面可读
栈就是访问存储器,这个时间代价比访问寄存器 访问权限位字段
高 PROT_WRITE:区域内页面可写
进程与进程的上下文切换
中断允许位:用于防止处理中断时响应新的中段 PROT_NONE:区域内页面不能被访问
的位,如果设置成1,称为开中断,此时能够响应
新的中断,如果设置成0,称为关中断,此时不 异常和中断的响应过程 例如可执行文件或者共享库文件,可将文件中的
能够响应新的中断 一个数据或者代码节划分成页面大小的片,每一
关中断
片局势一个虚拟页在内存页框中的初始内容
在中断响应的过程中,CPU通常将中断允许位清
零,以禁止响应新的可屏蔽中断 私有对象:包括只读代码区域和已初始化数据区
域,私有对象通过写时拷贝技术映射到虚拟地址
内部异常事件的识别通过CPU将事件对应的异常 空间,所映射的区域称为私有区域,对应的对象
类型号或者标识异常的记录信息记录到特定的内 mmap函数的功能 普通文件 称为私有的写时拷贝对象
部寄存器即可
共享对象:映射到共享库区域的对象
外部中断通过CPU的引脚INTR告知CPU中断的发
生,而CPU在每次执行完指令之后都会检查引脚 首先内核在主存上找到一个空闲的页框
的方式得知外部中断的产生
进程的存储器映射
CPU第一次访问对应的虚拟页面的流程
然后内核从硬盘上的文件中装入所映射对象的信
异常和中断源的识别可以采用软件识别或者硬件 息
识别异常和中断事件并转响应处理程序执行
识别
如果文件中的对象不是正好为页面大小的整数
软件识别:操作系统使用异常中断查询程序,对 倍,内核使用零来填充余下的部分
CPU中专门用于存放中断信息的寄存器进行查
询,检测异常和中断的类型 匿名文件由内核创建,全部由零组成
匿名文件
硬件识别:也称为向量中断方式,这种方式下, 请求零的页:匿名文件对应区域中的虚拟页
异常或中断处理程序的首地址被称为中断向量,
所有的中断向量存放在一个表中,称为中断向量 虚拟页第一次被装入内存以后,不管是由普通文
表,每个异常和中断都被设定一个中断类型号, 件还是匿名文件对其进行了初始化,以后都是在
中断向量存放的位置与对应的中断类型号相关, 主存页框和硬盘中作为交换文件进行调入和调出
通过类型号能够快速的找到对应的处理程序 交换文件
交换文件由内核进行管理和维护,也被称为交换
分区或者交换空间
一个进程对共享区域进行写操作的结果,对于所
有共享同一个共享对象的进程都是可见的,结果
也会反映在硬盘上对应的共享文件之中
私有的写时拷贝页:内核会将对应的多个进程的
同一个文件中的私有对象映射到进程各自的VM
用户空间区域之中,这些区域中的页面标记为私
有的写时拷贝页,内核将这些对应页表项中的访
问权限标记为只读
如果进程对私有的写时拷贝页进行了写操作,那
共享对象和私有的写时拷贝对象 么就与只读访问权限不相符,发生保护异常,内
核就会进行页故障处理
在页故障处理的过程中,如果内核发现异常是由
于进程对自己私有的写时拷贝对象进行写操作导
致的,那么内核就会在主存中为这个页面分配一
个新的页框,把页面内容拷贝到新页框中,并修
改进程对应的页表项,填入新分配的页框号,同
事修改访问权限为可读可写
这种方式充分的利用了主存的物理空间
加载器:常驻内存的操作系统程序,用来加载可
执行目标文件
首先加载程序加载并运行可执行目标文件,如果
找不到目标文件则返回-1,如果执行成功则不返
回而是将PC设定执行在可执行目标文件ELF头中
定义的入口点_start,符号_start在启动例程crtl.o
中定义,每个C语言程序都一样
符号_start处定义的启动代码主要是一系列过程调
用,首先依次调用_libc_init_first和_init两个初始
化过程
程序加载到执行的过程
然后通过调用atexit()过程对程序正常结束时需要
调用的函数进行登记注册,这些注册函数被称为
终止处理函数,将由exit()函数自动调用执行
然后在调用可执行目标函数中的main()函数,最
后调用_exit()过程以结束程序的执行,然后回到
操作系统内核
shell命令行解释器输出一个命令行提示符,并开
程序的加载和执行
始接受用户输入的命令行
用户在命令行输入./a.out后,开始对命令行进行
解析,获得各个命令行参数并构造传递给函数
execve()的参数列表argv,并将参数个数送argc
调用函数folk(),创建一个子进程并使新创建的子
可执行文件a.out的加载运行过程 进程获得与父进程完全相同的虚拟空间映射和页
表,并将父进程和子进程每一个私有页的访问权
限都设置成只读的,将两个进程vm_area_struct
中描述的私有区域中的页面说明为私有的写时拷
贝页
将命令行解析得到的参数个数argc,参数列表
argv以及全局变量environ作为参数,调用函数
execve(),从而实现在当前进程的上下文中加载
并运行a.out程序
删除已有的VM用户空间中的区域结构vm_area_
struct及其页表
execve()执行加载任务并启动程序运行的过程 根据可执行文件a.out的程序头表创建新进程VM
用户空间中个各个私有区域和共享区域,生成相
应的vm_area_struct链表并为每个区域页面生成
相应的页表项,其中私有区域包括只读代码、已
初始化数据、未初始化数据、栈和堆