【操作系统】异常控制流
异常控制流
CSAPP CH-8
指令地址间的过度为控制转移,控制转移序列叫做控制流
ECF Exceptional Control Flow 异常控制流是系统实现IO,进程和虚拟内存的基本机制
ECF用于应用程序和操作系统的交互
try catch等语句基于ECF
异常
硬件实现,操作系统实现
异常是控制流中的突变
比如虚拟内存缺页, 算术溢出, 除以0
事件:处理器状态变化
处理器检测到事件发生,通过异常表的跳转表,进行间接过程调用,由异常处理程序处理异常,根据异常事件类型,进行:
- 将控制返回给当前指令I-curr
- 控制返回给I-next,则没有发生异常,执行下一条指令
- 终止被中断的程序
异常处理
每种异常分配一个异常号,是异常表中的索引
系统启动时操作系统预处理一张异常表,第k个元素包含异常k的处理程序的地址
异常表基地址寄存器存放异常表的起始地址
过程调用和异常的区别:
- 过程调用,跳转回处理程序前,处理器将返回地址入栈;异常为根据异常以及处理结果进行跳转
- 处理器会将额外处理器状态入栈
- 控制从用户程序转移到内核,都被压入内核栈
- 异常处理运行在内核模式
硬件触发异常,异常处理程序在软件中完成
异常类型
中断 interrupt 来自IO设备 异步 返回到下一条指令
陷阱 trap 有意异常 同步 返回到下一条指令
故障 fault 潜在的可恢复错误 同步 可能返回当前指令
终止 abort 不可恢复错误 同步 不会返回
中断
异步发生,来自处理器外部的IO设备
异步的含义:中断不是由一个专门指令造成的
异常由中断处理程序处理
trap和系统调用
trap是指向指令的结果,用于在用户程序和内核之间提供一个接口,叫做系统调用
读文件,创建进程fork,加载程序
故障
由错误情况引起,被故障处理程序修正,控制返回到引起故障的指令,从而重新执行,否则返回到内核的abort,将引起故障的程序终止。
终止
硬件错误,dram或者sram损坏 会返回abort然后终止应用程序
Linux x86-64系统中的异常
故障号和cpu架构有关
Linux中的故障和终止
除法错误:除以0,Unix会直接终止程序 floating exception
一般故障保护:神秘的错误,如程序引用了未定义的虚拟内存地址,或者访问只读的文本,也就是段错误segmentation fault
缺页:会从新执行产生故障的指令,将磁盘上的虚拟内存的一个页面映射到物理内存的一个页面,然后重新执行这条指令
机器检查:是在导致故障的指令执行中检测到致命的硬件错误时发生的
系统调用
请求内核的服务
每个系统调用有一个编号,对应内核中跳转表的偏移量
c语言中syscall函数,c一般封装了系统调用库函数,带着参数陷入内核,将系统调用的执行状态返回
Linux系统调用的参数通过寄存器传递
进程
执行中程序的实例,每个程序运行在某个进程的上下文context中
上下文包括内存中程序的代码和数据,栈,通用目的寄存器,程序计数器,环境变量,文件描述符集合
提供抽象:独立的逻辑控制流,假象程序独占处理器;私有地址空间,假象程序独占内存
逻辑控制流是交错的,进程轮流使用处理器,每个进程执行流的一部分
并发流
逻辑流可以是进程、线程等
并发:多个流并发的执行
运行在同一个处理器上
并行:运行在不同处理器核上
每个控制流中的一部分是时间片
私有地址空间
进程为每个程序提供假象,n位地址机器,地址空间2^n
,
底部用于用户程序:包括代码,数据,堆,栈
顶部给内核
用户模式和内核模式
通过模式位寄存器控制
/proc文件系统,包含系统属性,如内核数,cpu类型,某进程使用的内存段地址
上下文切换
实现多任务
内核为每个进程维护一个上下文,包含重新启动一个进程所需的状态
包含通用目的寄存器,浮点寄存器,程序计数器,用户栈,状态寄存器,内核栈,内核数据结构(描述地址空间的页表、当前进程信息的进程表、已打开文件的文件表)
内核可以通过调度决定执行哪个进程
- 保存当前进程上下文
- 恢复先前被抢占进程的上下文
- 控制传递给新恢复的进程
错误处理
全局变量 errno,strerror(errno)
进程控制
获取进程id
pid