20135213——信息安全系统设计基础第十周学习总结
第八章異常控制流
一、學(xué)習(xí)目標(biāo)
1. 了解異常及其種類
2. 理解進(jìn)程和并發(fā)的概念
3. 掌握進(jìn)程創(chuàng)建和控制的系統(tǒng)調(diào)用及函數(shù)使用:fork,exec,wait,waitpid,exit,getpid,getppid,sleep,pause,setenv,unsetenv,
4. ?理解數(shù)組指針、指針數(shù)組、函數(shù)指針、指針函數(shù)的區(qū)別
5. 理解信號(hào)機(jī)制:kill,alarm,signal,sigaction
6. 掌握管道和I/O重定向:pipe, dup, dup2
?
二、學(xué)習(xí)資源
1. 教材:第八章《異常控制流》
2. 課程資料:https://www.shiyanlou.com/courses/413?? 實(shí)驗(yàn)九,課程邀請(qǐng)碼:W7FQKW4Y
3. 教材中代碼和習(xí)題中代碼運(yùn)行、思考一下,讀代碼的學(xué)習(xí)方法見(jiàn)這。
?
三、學(xué)習(xí)任務(wù)
1. 閱讀教材,完成課后練習(xí)(書中有參考答案)
2. 考核:練習(xí)題把數(shù)據(jù)變換一下
3. 加分題:課后作業(yè)最多兩人一組,互相不能重復(fù),1星題目每人最多加一分,2星題目每人最多加二分,3星題目每人最多加三分,4星題目每人最多加四分。
?
四、學(xué)習(xí)過(guò)程
8.1 異常
從處理器運(yùn)行開(kāi)始到結(jié)束,程序計(jì)數(shù)器假設(shè)一個(gè)序列的值a0a1......an-1,這個(gè)控制轉(zhuǎn)義序列叫做處理器的控制流,異常,就是控制流中的突變,用來(lái)響應(yīng)處理器狀態(tài)中的某些變化。
狀態(tài)的變化稱為事件,在任何情況下,當(dāng)處理器檢測(cè)到有事件發(fā)生時(shí),會(huì)通過(guò)一張叫做異常表的跳轉(zhuǎn)表,進(jìn)行一個(gè)間接過(guò)程調(diào)用到專門處理程序——異常處理程序。當(dāng)異常處理程序完成之后,根據(jù)引起引起異常的事件類型,會(huì)發(fā)生以下三種情況之一:
- 處理程序?qū)⒖刂品祷亟o當(dāng)前指令,即事件發(fā)生之時(shí)正在執(zhí)行的指令。
- 處理程序?qū)⒖刂品祷亟o如果沒(méi)有異常將會(huì)執(zhí)行的下一條指令。
- 處理程序終止被中斷的程序。
異常處理
系統(tǒng)中可能的每種異常都被分配了唯一一個(gè)非負(fù)整數(shù)的異常號(hào),異常表中的條目k中包含異常k的處理程序地址。異常表的起始地址存放在一個(gè)叫做異常表基址寄存器的特殊寄存器中。
異常類和過(guò)程調(diào)用的不同之處:
- 返回地址是當(dāng)前地址或者下一條指令
- 處理器也會(huì)把額外的處理器狀態(tài)壓回棧中,在處理程序返回時(shí),重新開(kāi)始被中斷的程序會(huì)需要這些狀態(tài)。
- 如果控制從一個(gè)用戶程序轉(zhuǎn)移到內(nèi)核,那么所有項(xiàng)目都會(huì)被壓到內(nèi)核棧中而不是用戶棧。
- 異常處理程序運(yùn)行在內(nèi)核模式下,意味著他們對(duì)所有的系統(tǒng)資源擁有完全的訪問(wèn)權(quán)限。
異常的類別
?
1.中斷
中斷是異步發(fā)生的,是來(lái)自處理器外部的I/O設(shè)備的信號(hào)的結(jié)果。因此是異步的。硬件中斷的異常處理程序通常稱為中斷處理程序。
其余異常類型都是同步發(fā)生的,是執(zhí)行當(dāng)前指令的結(jié)果。這一類指令稱為故障指令。
2.陷阱
陷阱是有意的異常,最重要的用途是在用戶程序和內(nèi)核之間提供一個(gè)向過(guò)程一樣的接口,叫做系統(tǒng)調(diào)用。
為了允許內(nèi)核服務(wù)的受控訪問(wèn),使用“syscall n”指令,跳轉(zhuǎn)到一個(gè)異常處理程序的陷阱,處理程序?qū)?shù)解碼并調(diào)用適當(dāng)?shù)膬?nèi)核程序。
3.故障
故障由錯(cuò)誤情況引起,可能能夠被故障處理程序修正。故障發(fā)生時(shí),處理器將控制轉(zhuǎn)移給故障處理程序,若能修正,則將控制返回到引起故障的指令,重新執(zhí)行;若不能修正,處理程序返回abort例程,終止引起故障的應(yīng)用程序。
4.終止
終止是不可恢復(fù)的致命錯(cuò)誤造成的結(jié)果,通常是硬件錯(cuò)誤。終止處理程序?qū)⒖刂浦苯臃祷亟oabort例程,直接終止該應(yīng)用程序。
Linux/A32系統(tǒng)中的異常
Linux/A32故障和終止
- 除法錯(cuò)誤(異常0):應(yīng)用試圖除以0,或者除法指令的結(jié)果對(duì)于目標(biāo)操作數(shù)過(guò)大。
- 一般故障保護(hù)(異常13):通常因?yàn)橐粋€(gè)程序引用一個(gè)未定義的虛擬存儲(chǔ)區(qū)域,或者試圖寫一個(gè)只讀文本段。
- 缺頁(yè)(異常14):處理程序?qū)⒋疟P上虛擬存儲(chǔ)器相應(yīng)頁(yè)面映射到物理存儲(chǔ)器的一個(gè)頁(yè)面,然后重新開(kāi)始執(zhí)行這條指令。
- 機(jī)器檢查(異常18):在導(dǎo)致故障的指令執(zhí)行中檢測(cè)到致命的硬件錯(cuò)誤。
Linux/A32系統(tǒng)調(diào)用
每個(gè)系統(tǒng)調(diào)用都對(duì)應(yīng)著唯一的整數(shù)號(hào),對(duì)應(yīng)于一個(gè)到內(nèi)核中跳轉(zhuǎn)表的偏移量。
IA32系統(tǒng)調(diào)用是通過(guò)一條稱為 int n 的陷阱指令提供的。
C程序通過(guò)syscall函數(shù)可以直接調(diào)用任何系統(tǒng)調(diào)用。
所有Linux系統(tǒng)調(diào)用都是通過(guò)通用寄存器而不是棧傳遞的,%eax包含系統(tǒng)調(diào)用號(hào),%ebx、%ecx、%edx、esi%、%edi和%ebp包含最多6個(gè)參數(shù)。棧指針%esp不能使用,因?yàn)楫?dāng)進(jìn)入內(nèi)核模式時(shí),內(nèi)核會(huì)覆蓋它。
?
8.2 進(jìn)程
進(jìn)程的經(jīng)典定義:一個(gè)執(zhí)行中的程序的實(shí)例。
系統(tǒng)中的每個(gè)程序都是運(yùn)行在某個(gè)進(jìn)程的上下文中的。
上下文:由程序正確運(yùn)行所需的狀態(tài)組成的。
進(jìn)程提供給應(yīng)用程序的關(guān)鍵抽象:
一個(gè)獨(dú)立的邏輯控制流:獨(dú)占的使用處理器
一個(gè)私有的地址空間:獨(dú)占的使用存儲(chǔ)器系統(tǒng)
1.邏輯控制流
(1)含義:
一系列的程序計(jì)數(shù)器PC的值,分別唯一的對(duì)應(yīng)于包含子啊程序的可執(zhí)行目標(biāo)文件中的指令,或者是包含在運(yùn)行時(shí)動(dòng)態(tài)鏈接到程序的共享對(duì)象中的指令,這個(gè)PC值的序列就叫做邏輯控制流。
(2)運(yùn)行:
進(jìn)程輪流使用處理器,每個(gè)進(jìn)程執(zhí)行流的一部分,然后被搶占(暫時(shí)掛起)。每個(gè)進(jìn)程執(zhí)行它的流的一部分,然后被搶占,然后輪到其他進(jìn)程。但是進(jìn)程可以向每個(gè)程序提供一種假象,好像它在獨(dú)占的使用處理器。
(3)示例:
異常處理程序、進(jìn)程、信號(hào)處理程序、線程、Java進(jìn)程
2.并發(fā)流
(1)含義
一個(gè)邏輯流的執(zhí)行在時(shí)間上與另一個(gè)流重疊。【與是否在同一處理器無(wú)關(guān)】
這兩個(gè)流并發(fā)的運(yùn)行。
(2)幾個(gè)概念
并發(fā):多個(gè)流并發(fā)的執(zhí)行
多任務(wù):一個(gè)進(jìn)程和其他進(jìn)程輪流運(yùn)行(也叫時(shí)間分片)
時(shí)間片:一個(gè)進(jìn)程執(zhí)行它的控制流的一部分的每一時(shí)間段
(3)并行
兩個(gè)流并發(fā)的運(yùn)行在不同的處理機(jī)核或者計(jì)算機(jī)上。
并行流并行的運(yùn)行,并行的執(zhí)行。
3.私有地址空間
進(jìn)程為程序提供的假象,好像它獨(dú)占的使用系統(tǒng)地址空間。一般而言,和這個(gè)空間中某個(gè)地址相關(guān)聯(lián)的那個(gè)存儲(chǔ)器字節(jié)是不能被其他進(jìn)程讀寫的。
4.用戶模式和內(nèi)核模式
處理器通常是用某個(gè)控制寄存器中的一個(gè)模式位來(lái)提供這種功能的,該寄存器描述了進(jìn)程當(dāng)前享有的特權(quán)。
當(dāng)設(shè)置了模式位時(shí),進(jìn)程就運(yùn)行在內(nèi)核模式中(超級(jí)用戶模式)。
沒(méi)有設(shè)置模式位時(shí),進(jìn)程就運(yùn)行在用戶模式中。
進(jìn)程從用戶模式變?yōu)閮?nèi)核模式的唯一方法是通過(guò)中斷、故障或者陷入系統(tǒng)調(diào)用這樣的異常實(shí)現(xiàn)的。
Linux提供/proc文件系統(tǒng),允許用戶模式進(jìn)程訪問(wèn)內(nèi)和數(shù)據(jù)結(jié)構(gòu)的內(nèi)容。
5.上下文切換
上下文:內(nèi)核重新啟動(dòng)一個(gè)被搶占的進(jìn)程所需的狀態(tài)
操作系統(tǒng)內(nèi)核使用上下文切換的較高層形式的異常控制流來(lái)實(shí)現(xiàn)多任務(wù)。
內(nèi)核為每個(gè)進(jìn)程維持一個(gè)上下文。
在進(jìn)程執(zhí)行的某些時(shí)刻,內(nèi)核可以決定搶占當(dāng)前進(jìn)程,并重新開(kāi)始一個(gè)先前被搶占的進(jìn)程,成為調(diào)度。
由內(nèi)核中成為調(diào)度器的代碼處理的。
使用上下文切換的機(jī)制來(lái)控制轉(zhuǎn)移到新的進(jìn)程
保存當(dāng)前進(jìn)程的上下文
恢復(fù)某個(gè)先前被搶占的進(jìn)程被保存的上下文
將控制傳遞給這個(gè)新恢復(fù)的進(jìn)程
8.3 系統(tǒng)調(diào)用錯(cuò)誤處理
- 當(dāng)Unix系統(tǒng)級(jí)函數(shù)遇到錯(cuò)誤時(shí),它們典型地會(huì)返回-1,并設(shè)置全局證書變量errno來(lái)表示什么出錯(cuò)了。
?
8.4進(jìn)程控制
獲取進(jìn)程ID
#include <sys/types.h>#include <unistd.h>pid_t getpid(void); 返回調(diào)用進(jìn)程的PID pid_t getppid(void);返回父進(jìn)程的PID(創(chuàng)建調(diào)用進(jìn)程的進(jìn)程)-
getpid和getppid函數(shù)返回一個(gè)類型為pid_t的整數(shù)值,在Linux系統(tǒng)上它在types.h中被定義為int
創(chuàng)建和終止進(jìn)程
-
進(jìn)程總是處于下面三種狀態(tài)之一
- 運(yùn)行
- 停止:被掛起且不會(huì)被調(diào)度
-
終止:進(jìn)程永遠(yuǎn)停止
-
終止原因:
- 收到一個(gè)信號(hào),該信號(hào)的默認(rèn)行為是終止進(jìn)程
- 從主程序返回
- 調(diào)用exit函數(shù)
-
-
父進(jìn)程通過(guò)調(diào)用fork函數(shù)創(chuàng)建一個(gè)新的運(yùn)行子進(jìn)程:
#include <sys/types.h> #include <unistd.h>pid_t fork(void); - 子進(jìn)程返回0,父進(jìn)程返回子進(jìn)程的PID,如果出錯(cuò),則為-1.
-
父進(jìn)程和新創(chuàng)建的子進(jìn)程之間最大的區(qū)別:
- 它們有不同的PID
-
fork函數(shù)只被調(diào)用一次,卻返回兩次。
- 一次是在父進(jìn)程中
- 一次是在新創(chuàng)建的子進(jìn)程中
- 在父進(jìn)程中,fork返回子進(jìn)程的PID
- 在子進(jìn)程中,fork返回0.
- 子進(jìn)程的PID總是非零的。
-
fork函數(shù)的并發(fā)執(zhí)行
- 父進(jìn)程和子進(jìn)程是并發(fā)運(yùn)行的獨(dú)立進(jìn)程
-
fork函數(shù)的相同的但是獨(dú)立的地址空間
-
fork函數(shù)的共享文件
-
調(diào)用fork函數(shù)n次,產(chǎn)生2的n次方個(gè)進(jìn)程
回收子進(jìn)程
- 一個(gè)終止了但還未被回收的進(jìn)程稱為僵死進(jìn)程。
- 如果父進(jìn)程沒(méi)有回收它的僵死子進(jìn)程就終止了,那么內(nèi)核就會(huì)安排init進(jìn)程來(lái)回收它們。
-
一個(gè)進(jìn)程可以通過(guò)調(diào)用waitpid函數(shù)來(lái)等待它的子進(jìn)程終止或者停止。
- 成功返回子進(jìn)程PID,如果WNOHANG,返回0,其他錯(cuò)誤返回-1.
-
判定等待集合的成員
- 如果pid>0,那么等待集合就是一個(gè)單獨(dú)的子進(jìn)程,它的進(jìn)程ID等于pid。
- 如果pid=-1,那么等待集合就是由父進(jìn)程所有的子進(jìn)程組成的。
-
修改默認(rèn)行為
-
可以通過(guò)將optioins設(shè)置為常量WNOHANG和WUNTRACED的各種組合。
-
WNOHANG:如果等待集合中的任何子進(jìn)程都還沒(méi)有終止,那么就立即返回(返回值為0)。默認(rèn)的行為是掛起調(diào)用進(jìn)程,直到有子進(jìn)程終止。
-
WUNTRACED:掛起調(diào)用進(jìn)程的執(zhí)行,直到等待集合中的一個(gè)進(jìn)程變成已終止或者被停止。返回的PID為導(dǎo)致返回的已終止或被停止子進(jìn)程的PID。默認(rèn)的行為是只返回已終止的子進(jìn)程。
-
WNOHANG|WUNTRACED:i級(jí)返回如果等待集合中沒(méi)有任何子進(jìn)程被停止或已終止的子進(jìn)程。檢查已終止和被停止的子進(jìn)程時(shí),該選項(xiàng)會(huì)有用。
-
-
-
檢查已回收子進(jìn)程的退出狀態(tài)
-
wait.h頭文件定義了結(jié)束status參數(shù)的幾個(gè)宏:
- WIFEXITED:如果子進(jìn)程通過(guò)調(diào)用exit或者一個(gè)返回正常終止,就返回真。
- WEXXITSTATUS:返回一個(gè)正常終止的子進(jìn)程的退出狀態(tài)。只有在WIFEXITED返回為真時(shí),才會(huì)定義這個(gè)狀態(tài)。
- WIFSIGNALED:如果子進(jìn)程時(shí)因?yàn)橐粋€(gè)未被捕獲的信號(hào)終止的,那么就返回真。
- WTERMSIG:返回導(dǎo)致子進(jìn)程終止的信號(hào)的數(shù)量。只有在WIFSIGNALED返回為真時(shí),才定義這個(gè)狀態(tài)。
- WIFSTOPPED:如果引起返回的子進(jìn)程當(dāng)前是被停止的,那么就返回真。
- WSTOPSIG:返回引起子進(jìn)程停止的信號(hào)的數(shù)量。只有在WIFSTOPPED返回為真時(shí),才定義這個(gè)狀態(tài)。
-
-
錯(cuò)誤條件
- 如果調(diào)用進(jìn)程沒(méi)有子進(jìn)程,那么waitpid返回-1,并且設(shè)置errno為ECHILD。
- 如果waitpid函數(shù)被一個(gè)信號(hào)中斷,那么它返回-1,并設(shè)置errno為EINTR。
wait函數(shù)
- 其是waitpid函數(shù)的簡(jiǎn)單版本
- 調(diào)用wait(&status)等價(jià)于調(diào)用waitpid(-1,&status,0)
讓進(jìn)程休眠
- sleep函數(shù)將一個(gè)進(jìn)程掛起一段指定的時(shí)間
- 如果請(qǐng)求的時(shí)間量已經(jīng)到了,sleep返回0,否則返回還剩下的要休眠的秒數(shù)。
- pause函數(shù)讓調(diào)用函數(shù)休眠,直到該進(jìn)程收到一個(gè)信號(hào)。
加載并運(yùn)行程序
- execve函數(shù)加載并運(yùn)行可執(zhí)行目標(biāo)文件filename,且?guī)?shù)列表argv和環(huán)境變量列表envp。
- 只有出現(xiàn)錯(cuò)誤時(shí),execve才會(huì)返回到調(diào)用程序。
- 調(diào)用一次并從不返回。
- getenv函數(shù)在環(huán)境數(shù)據(jù)中搜索字符串"name=value",如果找到了,它就返回一個(gè)指向value的指針,否則它就返回NULL。
- 如果環(huán)境數(shù)據(jù)包含一個(gè)形如“name=oldvalue”的字符串,那么unsetenv會(huì)刪除它,而setenv會(huì)用newvalue代替oldvalue,但是只有在overwrite非零時(shí)才會(huì)這樣。如果name不存在,那么setenv就把“name=newvalue”添加到數(shù)組中。
?讓進(jìn)程休眠
1.sleep函數(shù)
sleep函數(shù)使一個(gè)進(jìn)程掛起一段指定的時(shí)間。定義如下:
#include <unistd.h>unsigned int sleep(unsigned int secs);返回值是剩下還要休眠的秒數(shù),如果到了返回0.
2.pause函數(shù)
#include <unistd.h>int pause(void);讓調(diào)用函數(shù)休眠,直到該進(jìn)程收到一個(gè)信號(hào)。
?加載并運(yùn)行程序——execve函數(shù)
#include <unistd.h>int execve(const char *filename, const char *argv[], const char *envp[]); 成功不返回,失敗返回-1.execve函數(shù)調(diào)用一次,從不返回。
- filename:可執(zhí)行目標(biāo)文件
- argv:參數(shù)列表
- envp:環(huán)境列表
新程序開(kāi)始時(shí):
getnev函數(shù)
#include <stdlib.h>char *getenv(const char *name); 若存在則為指向name的指針,無(wú)匹配是null在環(huán)境數(shù)組中搜尋字符串"name=value",如果找到了就返回一個(gè)指向value的指針,否則返回null。
setenv和unsetenv函數(shù)
#include <stdlib.h>int setenv(const char *name, const char *newvalue, int overwrite); 若成功返回0,錯(cuò)誤返回-1 void unsetenv(const char *name); 無(wú)返回值如果環(huán)境數(shù)組包含"name=oldvalue"的字符串,unsetenv會(huì)刪除它,setenv會(huì)用newvalue代替oldvalue,只有在overwrite非零時(shí)成立。
如果name不存在,setenv會(huì)將"name=newvalue"寫進(jìn)數(shù)組。
※fork函數(shù)和execve函數(shù)的區(qū)別
-
fork函數(shù)是創(chuàng)建新的子進(jìn)程,是父進(jìn)程的復(fù)制體,在新的子進(jìn)程中運(yùn)行相同的程序,父進(jìn)程和子進(jìn)程有相同的文件表,但是不同的PID
-
execve函數(shù)在當(dāng)前進(jìn)程的上下文中加載并運(yùn)行一個(gè)新的程序,會(huì)覆蓋當(dāng)前進(jìn)程的地址空間,但是沒(méi)有創(chuàng)建一個(gè)新進(jìn)程,有相同的PID,繼承文件描述符。
?
?
8.5信號(hào)
-
Unix信號(hào):更高層的軟件形式的異常允許進(jìn)程中斷其他進(jìn)程。
信號(hào)術(shù)語(yǔ)
-
傳遞一個(gè)信號(hào)到目的進(jìn)程的兩個(gè)步驟:
- 發(fā)送信號(hào)
- 接收信號(hào)
-
發(fā)送信號(hào)的原因:
- 內(nèi)核檢測(cè)到一個(gè)系統(tǒng)事件
- 一個(gè)進(jìn)程調(diào)用了kill函數(shù),顯式的要求內(nèi)核發(fā)送一個(gè)信號(hào)給目的進(jìn)程。
-
一個(gè)進(jìn)程可以發(fā)送信號(hào)給它自己。
-
接收信號(hào):
- 1.忽略
- 2.終止
- 3.執(zhí)行信號(hào)處理程序,捕獲信號(hào)
-
待處理信號(hào):
- 只發(fā)出沒(méi)有被接收的信號(hào)
- 任何時(shí)刻,一種類型至多只會(huì)有一個(gè)待處理信號(hào),多的會(huì)被直接丟棄
- 一個(gè)進(jìn)程可以選擇性的阻塞接受某種信號(hào),被阻塞仍可以被發(fā)送,但是不會(huì)被接收
- 一個(gè)待處理信號(hào)最多只能被接收一次。
- pending:待處理信號(hào)集合
-
blocked:被阻塞信號(hào)集合。
發(fā)送信號(hào)——基于進(jìn)程組
-
進(jìn)程組
- 每個(gè)進(jìn)程都只屬于一個(gè)進(jìn)程組。
- 進(jìn)程組ID:正整數(shù)
- 一個(gè)子進(jìn)程和他的父進(jìn)程屬于同一進(jìn)程組。
- 查看進(jìn)程組id:getpgrp
- 修改進(jìn)程組:setpgid
-
用/bin/kill程序發(fā)送信號(hào)
-
/bin/kill程序可以向另外的進(jìn)程發(fā)送任意的信號(hào),格式是:
- /bin/kill -n m
- n是信號(hào),m是進(jìn)程或進(jìn)程組
- 當(dāng)n>0時(shí),發(fā)送信號(hào)n到進(jìn)程m
-
當(dāng)n<0時(shí),使信號(hào)|n|發(fā)送到進(jìn)程組m中的所有進(jìn)程。
-
-
從鍵盤發(fā)送信號(hào)
- 在鍵盤輸入ctrl-c會(huì)導(dǎo)致一個(gè)SIGINT信號(hào)被發(fā)送到外殼。
- 外殼捕獲該信號(hào),然后發(fā)送SIGINT信號(hào)到這個(gè)前臺(tái)進(jìn)程組中的每個(gè)進(jìn)程。
- 在默認(rèn)情況下,結(jié)果是終止前臺(tái)作業(yè)。
- 輸入ctrl-z會(huì)發(fā)送一個(gè)SIGTSTP信號(hào)到外殼,外殼捕獲這個(gè)信號(hào),并發(fā)送SIGTSTP信號(hào)給前臺(tái)進(jìn)程組中的每個(gè)進(jìn)程。
- 在默認(rèn)情況下結(jié)果時(shí)停止前臺(tái)作業(yè)。
-
用kill函數(shù)發(fā)送信號(hào)
- 進(jìn)程通過(guò)調(diào)用kill函數(shù)發(fā)送信號(hào)給其他進(jìn)程(包括它們自己)
-
用alarm函數(shù)發(fā)送信號(hào)
- 進(jìn)程可以通過(guò)調(diào)用alarm函數(shù)向它自己發(fā)送SIGALRM信號(hào)。
-
接收信號(hào)
-
信號(hào)類型的預(yù)定義的默認(rèn)行為:
- 進(jìn)程終止
- 進(jìn)程終止并轉(zhuǎn)儲(chǔ)存儲(chǔ)器
- 進(jìn)程停止直到被SIGCONT信號(hào)重啟
- 進(jìn)程忽略該信號(hào)
-
signal函數(shù)通過(guò)下列三種方法來(lái)改變和信號(hào)signum相關(guān)聯(lián)的行為:
- 如果handler是SIG_IGN,那么忽略類型為signum的信號(hào)。
- 如果handler是SIG_DFL,那么類型為signum的信號(hào)行為恢復(fù)為默認(rèn)行為。
- 否則,handler就是用戶定義的函數(shù)的地址,這個(gè)函數(shù)稱為信號(hào)處理程序,只要進(jìn)程接收到一個(gè)類型為signum的信號(hào),就會(huì)調(diào)用這個(gè)程序。
- 通過(guò)把狐貍程序的抵制傳遞到signal函數(shù)從而改變默認(rèn)行為,稱為設(shè)置信號(hào)處理程序。
- 調(diào)用信號(hào)處理程序稱為捕獲信號(hào)
- 執(zhí)行信號(hào)處理程序稱為處理信號(hào)
-
信號(hào)處理問(wèn)題
* 待處理信號(hào)被阻塞 * 帶處理信號(hào)不會(huì)排隊(duì)等待 * 系統(tǒng)調(diào)用可以被中斷 * 不可以用信號(hào)來(lái)對(duì)其他進(jìn)程中發(fā)生的事件計(jì)數(shù)可移植的信號(hào)處理
-
Signal包裝函數(shù)設(shè)置了一個(gè)信號(hào)處理程序,其信號(hào)處理語(yǔ)義如下:
- 只有這個(gè)處理程序當(dāng)前正在處理的那種類型的信號(hào)被阻塞。
- 和所有信號(hào)實(shí)現(xiàn)一樣,信號(hào)不會(huì)排隊(duì)等待。
- 只要可能,被中斷的系統(tǒng)調(diào)用會(huì)自動(dòng)重啟。
- 一旦設(shè)置了信號(hào)處理程序,它就會(huì)移至保持,直到Signal帶著handler參數(shù)為SIG_IGN或者SIG_DFL被調(diào)用。
顯式地阻塞和取消阻塞信號(hào) p517
-
sigprocmask函數(shù)改變當(dāng)前已阻塞信號(hào)的集合,具體行為依賴于how值:
- SIG_BLOCK:添加set中的信號(hào)到blocked中(blocked = blocked | set)
- SIG_UNBLOCK:從blocked中刪除set的信號(hào)(blocked = blocked &~ set)
- SIG_SETMASK:blocked = set
- 如果oldset非空,blocked位向量以前的值會(huì)保存在oldset中。
非本地跳轉(zhuǎn)
-
用戶級(jí)的異常控制流形式,通過(guò)setjmp和longjmp函數(shù)提供。
-
setjump函數(shù)在env緩沖區(qū)中保存當(dāng)前調(diào)用環(huán)境,以供后面longjmp使用,并返回0.
-
調(diào)用環(huán)境:程序計(jì)數(shù)器,棧指針,通用目的寄存器
-
longjmp函數(shù)從env緩沖區(qū)中恢復(fù)調(diào)用環(huán)境,然后觸發(fā)一個(gè)從最近一次初始化env的setjmp調(diào)用的返回。然后setjmp返回,并帶有非零的返回值retval。
-
setjmp函數(shù)只被調(diào)用一次,但返回多次;
-
longjmp函數(shù)被調(diào)用一次,但從不返回。
操作進(jìn)程的工具
- STRACE:打印一個(gè)正在運(yùn)行的程序和他的子程序調(diào)用的每個(gè)系統(tǒng)調(diào)用的痕跡
- PS:列出當(dāng)前系統(tǒng)中的進(jìn)程,包括僵死進(jìn)程
- TOP:打印出關(guān)于當(dāng)前進(jìn)程資源使用的信息
- PMAP:顯示進(jìn)程的存儲(chǔ)器映射
轉(zhuǎn)載于:https://www.cnblogs.com/20135213lhj/p/4986881.html
總結(jié)
以上是生活随笔為你收集整理的20135213——信息安全系统设计基础第十周学习总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 英文情侣id257个
- 下一篇: android 跳转到系统设置界面的所有