20145313張雪純《信息安全系統設計基礎》第11周學習總結
教材
- 異常控制流(ECF)
- 最簡單的“平滑序列”類型的控制流是指PC中相鄰的指令在存儲器中也相鄰。而異常控制流則是指程序變量表示的內部程序狀態中的變化、系統狀態的變化等突發情況使得控制系統做出的反映。
- 應用程序如何與操作系統實現交互。應用程序使用系統調用(system call)的ECF形式向操作系統請求服務;實現并發的基本機制;提供軟件異常機制等等
- 異常
- 處理器中的變化(事件)觸發從應用程序到異常處理程序的突發的控制轉移,也就是異常。比如:被零除,缺頁,存儲器訪問違例,斷點,算術溢出;系統調用,來著外部I/O設備的信號等等。
- 在任何情況下,當處理器檢測到有事件發生時,它就會通過一張叫做異常表的跳轉表進行一個間接過程調用,到一個專門處理這類時間的操作系統子程序(異常處理程序);當 exception handler處理結束之后,會有三種結果 :處理程序將控制返回給事件發生的時候正在執行的指令;處理程序將控制返回給如果沒有發生異常將會執行的下一條指令;處理程序終止被終端的程序
- 異常&過程調用
- 過程調用的時候,在跳轉到處理程序之前,處理器將返回地址壓入棧中。然而根據異常的類型,要么返回當前指令,要么返回下一條指令;
- 異常雖然類似于過程調用,但在壓入棧的數據方面有不同。它會把一些額外的處理器狀態壓入棧中;并且如果是轉移到內核的程序,壓入的是內核棧中;
- 異常處理程序運行在內核模式下,意味著它們對所有的系統資源都有完全的訪問權限
異常表,其條目k中包含著異常k的處理程序的地址。其中,異常表的起始地址放在異常表基址寄存器中,而異常號是異常表中的索引,相當于偏移地址
- 中斷(異常類型1)
- 原因:由I/O設備的信號引起的結果
- 類型:異步(不是由任何一條指令造成的)
- 處理:i/o設備,例如定時器芯片、網絡控制器等,通過處理器芯片上的一個引腳發信號,并將異常號(標識引起中斷的設備)放在系統總線上;在當前指令完成之后,處理器注意到引腳電壓變化,從系統總線中讀取異常信號,調用中斷處理程序處理中斷;處理器返回(無中斷的時候)應該執行的下一條指令。
陷阱(異常類型2)
- 原因:有意的異常,是執行指令的結果
- 類型:同步
- 處理:用戶程序需要或者希望向內核請求服務(比如創建或者終止進程、讀文件等)的時候,執行 syscall n(n是想要請求的服務號)指令;把控制權交給處理程序;陷阱處理程序運行;處理程序結束之后,返回到下一條指令。
- 故障(異常類型3)
- 原因:由潛在的可恢復的錯誤的情況引起
- 類型:同步;可能能夠被修復然后返回當前指令。
- 過程:當前指令導致故障;控制轉移給處理程序;故障處理程序運行,如果可以修正這個錯誤,就將控制引起故障的指令從而重新執行它;否則,返回內核中的abort例程,abort終止引起故障的程序。
- 終止(異常類型 4)
- 原因:由不可恢復的致命錯誤造成;通常是一些硬件錯誤
- 類型:同步
- 過程:發生致命硬件錯誤;傳遞控制給處理程序;處理程序將控制返回給abort例程,該例程終止此應用程序
進程
- 定義:一個執行中的程序的實例。系統中的每個程序都運行在某個進程的上下文中。上下文是由程序正確運行所需要的狀態組成的。這個狀態包括放在存儲器中的程序的代碼和數據等
- 進程提供給了應用程序幾個關鍵抽象:
- 一個獨立的邏輯控制流——提供好像程序獨占處理器的假象;
- 一個私有的地址空間——提供好像程序獨占存儲系統的假象;
- 邏輯控制流
- 進程計數器(PC)中的每一個值都唯一地對應于包含在程序的可執行目標文件中的指令,或者是包含在運行時動態鏈接的到程序的共享對象中的指令。這個PC值的序列叫做邏輯控制流。
- 進程是輪流使用處理器的;每個進程執行它的流的一部分然后被掛起,其他進程執行。 對于一個運行在其中一個進程上下文中的程序而言,它看上去就像是唯一地占用了處理器(只不過如果精確測量的話,會發現對于一個進程來說,它在執行期間好像被停頓了若干個很短的時間)。
- 并發流
- 計算機系統中有很多邏輯流的不同形式,比如異常處理程序、進程、信號處理程序等;一個邏輯流的執行在時間上與另一個流重疊,稱為并發流;多個流并發執行的現象稱為并發;一個進程和其他進程輪流運行,稱為多任務;又叫做時間分片。
- 如果兩個流并發地運行在不同的處理器核或者計算機上,那么我們稱它們為并行流。
- 私有地址空間
- 在一臺有n位地址的機器上,地址空間是一個2^n個可能地址的集合。一個進程為每個程序提供它自己的私有地址空間;一般而言,和這個空間中某個地址相關聯的那個存儲器字節是不能夠被其他進程讀或者寫的(所以說它是私有的)
- 存儲器內容通用結構:地址空間底部留給用戶程序,包括通常的文本、數據等;地址空間頂部保留給內核(包括內核在代表進程執行指令的時候使用的代碼、數據和棧)
- 進程控制
- 獲取ID每個進程都有一個唯一的進程ID(PID);getpid函數獲取進程的PID;getppid獲取創建調用進程的進程(即它的父進程)的PID。以上兩個函數的返回值為pid_t,在linux系統中,它在types.h中被定義為int
- 創建和終止進程:父進程通過調用fork函數來創建一個新的運行子進程。新創建的子進程擁有和父進程相同的,但是獨立的用戶級虛擬地址空間拷貝,包括文本、數據和bss段、堆和用戶棧等;子進程和父進程擁有獨立的地址空間,所以二者對某一相同變量值的修改是互相不受影響的。
- 終止進程
- 運行:進程要么在CPU上運行,要么在等待被執行且最終被內核調度;
- 停止:進程的執行被掛起,且不會被調度。【當進程收到SIGSTOP,SIGTSTP,SIDTTIN,SIGTTOU信號的時候,進程就會停止,并且保持停止直到它收到一個SIGCONT信號,在此時再次運行】
- 終止:進程永遠地停止。三種原因:1)收到一個信號,其默認為終止程序;2)從主程序返回;3)調用exit函數(exit(int stauts),其中status是退出狀態)
- 回收子進程:當一個進程由于某種原因終止的時候,內核并不是把它從系統中清除,而是保持在已經終止的狀態中,直到被它的父進程回收。這時,內核將子進程的退出狀態傳遞給父進程,然后拋棄已經終止的進程。這之后,該進程才可以說是“不存在”了。
- 等待回收子進程:一個進程可以通過調用waitpid函數來等待它的子進程終止或者停止。父進程創建N個子進程,然后子進程以一個唯一的退出狀態退出;waitpid函數被阻塞直到某個子進程終止,然后進入while循環測試是否是正常終止的;是正常的話就輸出;當回收了所有的子進程之后,再調用waitpid就返回-1,并且設置errno為ECHILD;如果不是正常終止的,就輸出一個錯誤消息
- 加載并運行程序
- 非本地跳轉:C語言提供了一種用戶級異常控制流形式,稱為非本地跳轉;它將一個函數轉移到一個當前正在執行的函數,而省略了調用-返回序列這一步
- 函數:setjmp,longjmp。setjmp函數在env緩沖區中保存當前調用環境(包括PC,棧指針,通用寄存器),以供后面的longjmp使用,并返回0;longjmp函數從env緩沖區中回復調用環境,然后觸發一個從最近一次初始化env開始的setjmp函數調用的返回;main函數先調用setjmp保存以前的調用環境,然后調用函數foo;foo調用bar;如果這兩個函數中一個遇到錯誤,就立即通過longjmp調用從setjmp返回;setjmp非零返回值指明了錯誤類型
- 應用:用于允許從一個深層嵌套的函數調用之中立即返回,而不是費力地解開棧。用于使一個信號處理程序分支到一個特殊的代碼位置而不是返回到被信號中斷了的指令的位置。在程序第一次啟動的時候,調用setjmp保存上下文環境;隨后主函數進入無限處理循環;用戶鍵入ctrl-c之后,外殼發送SIGINT信號給進程,該進程捕獲這個信號然后處理程序執行一個非本地跳轉,回到主函數開始的地方
代碼調試
- exec
代碼中實現的是ls的功能
- forkdemo1
打印進程pid,調用fork函數生成子進程,休眠一秒后再次打印進程id
- forkdemo2
調用兩次fork
- forkdemo3
fork產生子進程,父進程返回子進程pid
- forkdemo4
先打印進程pid,然后fork創建子進程,父進程返回子進程pid
- forkdemogdb
父進程打印兩句,休眠一秒,再打印一句;子進程打印一句,休眠一秒,再打印兩句
- psh1
調用函數
- psh2
加入了循環
testbuf1
testbuf2
testbuf3
內容格式化輸出到標準錯誤、輸出流中
- testpid
輸出當前進程pid和父進程pid
- waitdemo
如果有子進程,則終止子進程,成功返回子進程pid
- waitdemo2
把子進程分為3個狀態exit,sig和core
- environ
打印環境變量
- environvar
簡單打印環境變量表
- consumer
memset(void s,int ch,size_t n);將s中前n個字節用ch替換并返回s
open(const char pathname,int flags);第一個參數是欲打開的文件路徑字符串,第二個參數是打開方式
- producer
代碼托管
鏈接:http://git.oschina.net/entropy_z/Linux
學習進度條
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一周 | 200/200 | 1/1 | 20/20 | |
第二周 | 300/500 | 1/2 | 18/38 | |
第三周 | 500/1000 | 1/3 | 22/60 | |
第四周 | 150/1150 | 1/4 | 30/90 | |
第五周 | 150/1300 | 1/5 | 30/120 | |
第六周 | 50/1350 | 1/6 | 30/150 | |
第七周 | 50/1400 | 1/7 | 20/170 | |
第八周 | 50/1450 | 1/8 | 20/190 | |
第九周 | 50/1500 | 1/9 | 20/210 | |
第十周 | 300/1800 | 1/10 | 20/230 | |
第十一周 | 300/2100 | 1/11 | 20/250 |
參考資料
- 《深入理解計算機系統V2》學習指導