信息安全系统设计基础第十一周学习报告
信息安全系统设计基础第十一周学习报告
异常控制流
假设程序计数器有一个值的序列:a0,a1,a2,…,an-1
其中,每个ak是某个相应指令Ik的地址。
控制转移
:每次从ak到ak+1的过渡
控制流
:a0,a1,a2,…,an-1这样的控制转移序列
平滑序列
:每个Ik和Ik+1在存储器中相邻
突变
:Ik+1和Ik不相邻,由诸如跳转、调用和返回之类情况造成
突变,即异常控制流
8.1异常
异常处理程序完成后的三种可能结果:
1将控制返回给当前指令
2将控制返回给如果没有异常发生将会执行的下一条指令
3终止被中断的程序
异常号:到异常表的索引
异常表:一张跳转表,其中条目k包含异常k的处理程序代码的地址
异常表基址寄存器:存放异常表的起始地址
异常类型
:
中断
:
原因:来自I/O设备信号
异步
返回到下一条指令
陷阱
原因:有意的异常
同步
返回到下一条指令
故障
原因:潜在可恢复的错误
同步
可能返回到当前指令
终止
原因:不可恢复的错误
同步
不会返回
8.2进程
进程
:一个执行中的程序的实例
上下文
:程序正确运行所需的状态,包括存放在存储器中的代码和数据、它的栈、通用目的寄存器的内容、程序计数器、环境变量,打开文件描述符的集合。
关键抽象
:
-
独立的逻辑控制流,好像程序独占使用处理器
-
私有地址空间,好像程序独占使用存储器系统
逻辑控制流
:
一系列唯一地对应于包含在程序的可执行目标文件中的指令,或者是包含在运行时动态链接到程序的共享对象中的指令的PC值的序列
并发流
:一个逻辑流的执行在时间上与另一个流重叠
私有地址空间
:一般而言,和地址空间中某个地址相关联的那个存储器字节是不能被其他进程读或者写的。
内核模式
:(超级用户)当设置了模式位时,该进程可以执行指令集中的任何指令,并且可以访问系统中的任何存储器位置
用户模式
:当没有设置模式位,进程不允许执行特权指令,如停止处理器,改变模式位,或发起I/O操作,也不允许直接引用地址空间中内核区内的代码和数据。用户模式进程必须通过系统调用接口间接访问内核代码和数据。
/proc文件系统
:允许用户模式进程访问内核数据结构的内容,如:CPU类型,或者某个特殊进程使用的存储器段
/sys文件系统
:输出关于系统总线和设备的额外的底层信息
8.4进程控制
从程序员的角度,进程的三种状态:
运行
:要么在CPU上执行,要么在等待被执行且最终被内核调度
停止
:被挂起,且不会被调度
终止
:永远停止:1 受到默认行为终止进程的信号,2从主程序返回,3调用你exit函数,
Fork()的微妙方面
:
调用一次,返回两次;
并发执行
相同但是独立的地址空间
共享文件
僵死进程
:一个终止了但还未被回收的进程
pid_t waitpid(pid_t pid,int *status ,int options);
- 判定等待集合的成员
Pid>0:等待集合是一个单独的子进程,进程ID等于pid
Pid=-1,等待集合就是由父进程所有的子进程组成
- 修改默认行为:
WNOHANG:等待集合中的任何子进程都还没有终止,就立刻返回
WUNTRACED:挂起调用进程的执行,直到等待集合中的一个进程变成已终止或者被停止
- 检查已回收子进程的推出状态
加载并运行程序
int execve(const char *filename, const char *argv[],const char *envp[]);
如果成功,则不返回;如果错误,则返回-1
该函数加载并运行可执行目标文件filename,带参数列表argv和环境变量列表envp。
只有当出错,execve才返回到调用程序
Argv[0]是可执行目标文件的名字
Envp中每个串都是形如“NAME=VALUE”名字—数值对。
8.5信号
信号:一条通知进程系统中发生了一个某种类型事件的小消息
发送信号:
可能原因:
1,内核检测到一个系统事件
2,一个进程调用了kill函数
接受信号:
进程可以忽略,终止或者通过执行一个信号处理程序的用户层函数捕获这个信号
进程组:每个进程都只属于一个进程组,由一个正整数进程组ID来标识。默认地,一个子
进程和它的父进程同属于一个进程组。
用/bin/kill发送信号(P507)
用键盘发送信号
用kill函数发送信号(P508)
用alarma函数发送信号
接受信号:
SIGKILL:收到后默认终止接受进程
SIGCHLD:默认忽略这个信号
除了SIGSTOP和SIGKILL,其他信号的默认行为可以通过signal函数进行修改
8.6非本地跳转
#include <setjmp.h>
int setjmp(jmp_buf env);
int sigsetjump(sigjmp_buf env,int savesigs);
setjmp在env缓冲区中保存当前调用环境,包括程序寄存器、栈指针、通用目的寄存器。
#include <setjmp.h>
void longjmp(jmp_buf env,int retval);
void siglongjmp(sigjmp_buf env,int retval);
longjmp函数从env缓冲区中恢复调用环境,然后触发一个从最近一次初始化env的setjmp调用的返回。
非本地跳转的一个重要应用就是允许从一个深层嵌套的函数调用中立即返回,通常由检测到某个错误情况引起。