【操作系统】异常控制流

异常控制流

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类型,某进程使用的内存段地址

上下文切换

实现多任务

内核为每个进程维护一个上下文,包含重新启动一个进程所需的状态

包含通用目的寄存器,浮点寄存器,程序计数器,用户栈,状态寄存器,内核栈,内核数据结构(描述地址空间的页表、当前进程信息的进程表、已打开文件的文件表)

内核可以通过调度决定执行哪个进程

  1. 保存当前进程上下文
  2. 恢复先前被抢占进程的上下文
  3. 控制传递给新恢复的进程

错误处理

全局变量 errno,strerror(errno)

进程控制

获取进程id

pid

0%