信息安全系统设计基础第十周学习总结
第八章异常控制流
第一节 异常
异常就是控制流的突变,用来响应处理器状态中的某些变化。状态变化称为事件。在任何情况下,当处理器检测到有事件时,通过一张叫做异常表的跳转表,进行一个间接地过程调用,到一个专门设计用来处理这类时间的操作系统子程序
l 异常的类别:异常可以分为4类:中断(interrupt)、陷阱(trap)、故障(fault)和终止(abort)。
中断是异步发生的,是来自处理器外部的I/O设备的信号的结果。
陷阱是有意的异常,是执行一条指令的结果。陷阱的最重要用途是执行系统调用。
故障是错误引起的,它可能被故障处理程序修正。一个经典的故障实例是缺页异常
终止是不可恢复的致命错误的结果,通常是一些硬件错误。
l Linux/IA32系统中的异常
n Linux/IA32故障和终止
除法错误(异常0) Linux外壳通常会把除法错误报告为“浮点异常”(Floating exception)。
一般保护故障(异常13) 许多原因会导致不为人知的一般保护故障,通常是因为一个程序引用了一个未定义的虚拟存储器区域,或者是因为试图写一个只读的文本段。Linux不会试图恢复这类故障。Linux外壳通常将此报告为“段错误”(Segmentation fault)。
缺页(异常14) 会重新执行产生故障的指令的一个异常实例。
机器检查(异常18) 在导致故障的指令执行中检测到致命的硬件错误时发生的。机器检查处理程序从不返回控制给应用程序。
n Linux/IA32系统调用
每个Linux系统调用,都有一个唯一的整数号,对应一个到内核中跳转表的偏移量。
历史上,系统调用通过异常128(0x80)提供的。
C程序可以直接用syscall函数直接调用任何系统调用,然而,实际中机会没必要这么没做。对于大多数系统调用,标准C库提供了一组方便的包装函数。这些包装函数将参数打包到一起,以合适的系统调用号陷入内核,然后将系统调用的返回状态传递回调用程序。
所有的到Linux系统调用的参数都是通过寄存器而不是栈传递的。
注意:异常作为通用的术语,在必要时才区别异步异常(中断)和同步异常(陷阱、故障和终止)。
第二节:进程
l 进程的经典定义就是一个执行中的程序的实例。
l 进程提供给应用程序的关键抽象:一个独立的逻辑控制流,它提供一个假象,好像我们的程序独占地使用处理器。一个私有的地址空间,它提供一个假象,好像我们的程序独占地使用存储器系统。
l 一个逻辑流的执行在时间上与另一个流重叠,称为并发流(concurrent flow),这两个流称之为并发地执行。多个流并发地执行的一般现象称为并发(concurrency)。注意,并发的思想与流运行的处理器核数或者计算机数无关。如果两个流在时间上重叠,那它们就是并发的。如果两个流并发地运行在不同的处理器核或者计算机上,那么我们称它们为并行流(parallel flow)。
l Linux提供了一种聪明的机制,叫做/proc文件系统,它允许用户模式进程访问内核数据结构。2.6版本的Linux内核引入/sys文件系统,它输出关于系统总线和设备的额外的底层信息。
第三节:系统调用错误处理
当Unix系统级函数遇到错误时,它们典型地返回-1,并设置全局整数变量errno来表示什么出错了。
strerror函数返回一个文本串,描述了某个error值相关联的错误。
第四节:进程控制
l 每个进程都有一个唯一的正数进程ID(PID)。新创建的子进程几乎但不完全与父进程相同。子进程得到与父进程用户级虚拟地址空间相同的(但是独立的)一份拷贝。子进程还继承了父进程所有的打开文件。父进程和新创建的子进程之间最大的区别是他们有不同的PID。
l 在栈的顶部是main函数的三个参数:1)envp,它指向envp[]数组;2)argv,它指向argv[]数组;3)argc,它给出argv[]中非空指针的数量。
第五节:信号
对于只捕获一个信号并终止的程序来说,信号处理是简单直接的。然而当一个程序要捕获多个信号时,一些细微的问题就产生了。
待处理信号不会排队等待。任意类型至多只有一个待处理信号。如果有两个类型为k的信号传送到一个目的进程,而目的进程当前正在执行信号k的处理程序,所以信号k是阻塞的,那么第二个信号就被简单地丢弃,它不会排队等待。
系统调用可以被中断。像read、write和accept这样的系统调用,潜在地会阻塞进程一段较长的时间,称为慢速系统调用。在某些系统中,当处理程序捕获到一个信号时,被中断的慢速系统调用在信号处理程序返回时不再继续,而是立即返回给用户一个错误条件,并将errno设置为EINTR。
第六节:非本地跳转
C语言提供了一种用户级的异常控制流形式,称为非本地跳转(nonlocal jump),它将控制直接从一个函数转移到另一个当前正在执行的函数,而不需要正常的调用-返回序列。非本地跳转通过setjmp和longjmp函数来提供的。
第七节:操作进程的工具
Linux系统提供了大量的监控和操作进程的有用工具。
STRACE:打印一个正在运行程序和它的子进程调用的每个系统调用的轨迹。
PMAP:显示进程的存储器映射。