2017-2018-1 20155232 《資訊安全系統設計基礎》第十一周學習總結
教材學習内容總結
本周學習第9章:
- 虛拟存儲器的三個重要能力:
1.它将主存看成是一個存儲在磁盤上的位址空間的高速緩存,在主存中隻儲存活動區域,并根據需要在磁盤和主存之間來回傳送資料,通過這種方式,高效的使用了主存
2.它為每個程序提供了一緻的位址空間,進而簡化了存儲器管理
3.它保護了每個程序的位址空間不被其他程序破壞
- 實體和虛拟尋址
1.實體尋址
計算機系統的主存被組織成一個由M個連續的位元組大小的單元組成的數組,每位元組都有一個唯一的實體位址PA。根據實體位址尋址的是實體尋址。

2.虛拟尋址
使用虛拟尋址時,CPU通過生成一個虛拟位址VA來通路主存,這個虛拟位址在被送到存儲器之前先轉換成适當的實體位址,相關硬體為存儲器管理單元MMU。
3.位址翻譯
把一個虛拟位址轉換為實體位址的任務。需要CPU硬體和作業系統之間的緊密合作。
- Linux虛拟存儲器系統
Linux為每個程序維持一個單獨的虛拟位址空間:核心虛拟存儲器和程序虛拟存儲器。核心虛拟存儲器包含核心中的代碼和資料。
- 作用
允許虛拟位址空間有間隙;核心不用記錄那些不存在的頁,這樣的頁也不用占用存儲器
- 虛拟存儲器:虛拟頁VP,每個虛拟頁大小為P=2^平位元組
- 實體存儲器——實體頁PP,也叫頁幀,大小也為P位元組。
- DRAM緩存的組織結構
1.不命中處罰很大
2.是全相聯的——任何虛拟頁都可以放在任何的實體頁中。
3.替換算法精密
4.總是使用寫回而不是直寫。
- 頁表:是一個資料結構,存放在實體存儲器中,将虛拟頁映射到實體頁,就是一個頁表條目的數組。
# 2017-2018-1 20155232 《資訊安全系統設計基礎》第十一周學習總結 - Linux缺頁異常處理
MMU在試圖翻譯虛拟位址A時,觸發缺頁。這個異常導緻控制轉移到缺頁處理程式,執行如下步驟:
缺頁處理程式搜尋區域結構連結清單。把A和每個區域的vm_start和vm_end做比較。如果不合法,觸發段錯誤。
- fork函數
當fork函數被目前程序調用時:
核心為新程序建立核心資料結構,并配置設定給它唯一一個PID。
為新程序建立虛拟存儲器。
- execve函數:使用execve函數将a.out程式加載到存儲器的過程
具體的步驟如下:
删除已存在的使用者區域。
映射私有區域。
映射共享區域。
設定程式計數器。
- mmap函數
- 可以使用mmap函數來建立新的虛拟存儲器區域,并将對象映射到這些區域中 mmap();
- munmap函數删除虛拟存儲器的區域 munmap()。
- 動态存儲器配置設定
- 顯示配置設定器-malloc和free
- 隐式配置設定器/垃圾收集器
- 系統調用malloc函數,從堆中配置設定塊
- 系統調用free函數來釋放已配置設定的堆塊:
- 垃圾收集器是一種動态存儲配置設定器。,自動釋放程式已經不再需要的已配置設定塊(垃圾)。
- Mark&Sweep垃圾收集器
- C程式中常見的與存儲器有關的錯誤
間接引用壞指針:scanf錯誤
讀未初始化的存儲器:假設堆存儲器被初始化為0
允許棧緩沖區溢出:緩沖區溢出錯誤
假設指針和它們指向的對象是相同大小的
造成錯位錯誤
引用指針,而不是它所指向的對象
誤解指針運算
引用不存在的變量
引用空堆塊中的資料
引起存儲器洩露
教材學習中的問題和解決過程
- 段錯誤的幾種典型有什麼?如何解決?
- 解決:
在程式設計中以下幾類做法容易導緻段錯誤,基本上是錯誤地使用指針引起的。
1)通路系統資料區,尤其是往系統保護的記憶體位址寫資料最常見就是給一個指針以0位址。
2)記憶體越界(數組越界,變量類型不一緻等): 通路到不屬于你的記憶體區域。
段錯誤産生的原因
1.通路不存在的記憶體位址
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = NULL;
*ptr = 0;
}
2.通路系統保護的記憶體位址
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = (int *)0;
*ptr = 100;
}
3.通路隻讀的記憶體位址
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
char *ptr = "test";
strcpy(ptr, "TEST");
}
4.棧溢出
#include<stdio.h>
#include<stdlib.h>
void main()
{
main();
}
- 段錯誤的調試方法
1.使用printf輸出資訊
這個是看似最簡單但往往很多情況下十分有效的調試方式,也許可以說是程式員用的最多的調試方式。簡單來說,就是在程式的重要代碼附近加上像printf這類輸出資訊,這樣可以跟蹤并列印出段錯誤在代碼中可能出現的位置。
為了友善使用這種方法,可以使用條件編譯指令#ifdef DEBUG和#endif把printf函數包起來。這樣在程式編譯時,如果加上-DDEBUG參數就能檢視調試資訊;否則不加該參數就不會顯示調試資訊。
2.使用gcc和gdb
3.使用core檔案和gdb
4.使用objdump
- 使用catchsegv
具體的解決步驟參考
- 記憶體洩露和記憶體溢出有何不同?
- 記憶體洩漏也稱作“存儲滲漏”,用動态存儲配置設定函數動态開辟的空間,在使用完畢後未釋放,結果導緻一直占據該記憶體單元。直到程式結束。有人比喻是“作業系統可提供給所有程序的存儲空間正在被某個程序榨幹”,最終結果是程式運作時間越長,占用存儲空間越來越多,最終用盡全部存儲空間,整個系統崩潰。是以“記憶體洩漏”是從作業系統的角度來看的。這裡的存儲空間并不是指實體記憶體,而是指虛拟記憶體大小,這個虛拟記憶體大小取決于磁盤交換區設定的大小。由程式申請的一塊記憶體,如果沒有任何一個指針指向它,那麼這塊記憶體就洩漏了。
- 記憶體溢是指在一個域中輸入的資料超過它的要求而且沒有對此作出處理引發的資料溢出問題,多餘的資料就可以作為指令在計算機上運作。通常在運作大型軟體或遊戲時,軟體或遊戲所需要的記憶體遠遠超出了你主機内安裝的記憶體所承受大小,就叫記憶體溢出。此時軟體或遊戲就運作不了,系統會提示記憶體溢出,有時候會自動關閉軟體,重新開機電腦或者軟體後釋放掉一部分記憶體又可以正常運作該軟體或遊戲一段時間。
代碼調試中的問題和解決過程
本周暫無代碼調試問題
代碼托管
上周考試錯題總結
無
結對及互評
點評模闆:
暫無
本周結對學習情況
- 20155215
- 結對學習内容
- 共同學習課本9章和實驗樓内容
- 分析課本中代碼遇到的問題
- 結對學習内容
思考
本次的内容是學習第九章,這周内容有點難了解,看完最後一節C程式中常見的與存儲器有關的錯誤,看完之後覺得似曾相識,之前程式設計過程中就遇到很多類似的問題,每次都不知道是社麼原因導緻的,直接複制錯誤資訊,搜尋然後解決,現在大緻能弄懂是什麼原因引起的錯誤了。下次編代碼遇到類似的錯誤時就能夠更好的解決這些問題。
學習進度條
代碼行數(新增/累積) | 部落格量(新增/累積) | 學習時間(新增/累積) | 重要成長 |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小時 |
第四周 | 12/12 | 1/1 | 20/20 |
第五周 | 271/283 | 1/2 | 15/15 |
第6周 | 276/283 | 2/3 | 18/18 |
第7周 | 150/283 | 4/4 | 21/23 |
第8周 | 294/283 | 24/27 | |
第9周 | 289/283 | 29/23 | |
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進自己的計劃能力。這個工作學習中很重要,也很有用。 | |||
耗時估計的公式 | |||
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。 |
參考:軟體工程軟體的估計為什麼這麼難,軟體工程 估計方法
- 計劃學習時間:23小時
- 實際學習時間:29小時
(有空多看看現代軟體工程 課件
軟體工程師能力自我評價表)
參考資料
- 《深入了解計算機系統V3》學習指導
- ...