南昌大學工程實驗報告
學生姓名: 秦琦琛 學 号: 8000116xxx 專業班級: 軟工1611班
實驗類型:■ 驗證 □ 綜合 □ 設計 □ 創新 實驗日期: 2018、10、8 實驗成績:
一、實驗目的
熟悉linux程式設計環境,學會使用gcc、gdb和編寫工程管理檔案makefile。
- 實驗内容
- 将書中例題2-2和2-3調出結果,并編寫對應的帶參數的makefile檔案。
- 實驗要求
1.必須編制測試樣例,将程式中兩函數的差別展現。送出代碼截圖和運作結果截圖并附文字說明情況。
2.使用gdb工具,進行動态調試。檢視在輸入測試用例時,程式執行的情況。
3.實驗報告必須用南昌大學統一的實驗報告格式模闆制作,報告以sybg1.doc命名送出。
四、主要實驗步驟
1.建立如下檔案
如圖所示代碼,為本實驗頭檔案my.h。包含函數的定義以及必要頭檔案聲明
2.使用makefile管理檔案進行編譯
3.調試: 使用gdb指令調試,調試之前首先用gcc –g指令來生成調試資訊,否則調試失敗:
五、實驗資料及處理結果
1.測試樣例分析:兩函數的差別
(1)
使用fgets()函數:
輸入:1234567890 輸出:1234567 890\n
分析:p2-2.c中的memset()函數,将buffer結構體,16個位址空間用’\0’填充,fgets()函數以\0為結束符,當如上輸入時,buffer.buf的前7個記憶體位址存入’1234567’,最後一個記憶體位址用’\0’填充,剩下的’890\n’留在緩沖區,留待下一次讀取。第二次讀取’890\n’,以本來填充的’\0’作為讀取的結束符。故第二次輸出,輸出了換行。
此外,fgets()函數的讀取,并沒有發生溢出。每次讀取到n位空間時,從緩沖區讀取n-1位,最後一位函數自動設為’\0’作為結束符,剩下的留待下次讀取,不會出現溢出。
(2)
使用fgets()函數:
輸入:123456 輸出:123456\n
分析:此種情景,同上示例第二次讀取
(3)
使用gets()函數:
輸入:123456789123456789 輸出:123456789123456789
溢出:9123456789
分析:gets()函數以’\n’作為結束符。當如上輸入時,gets()函數從首位讀取,直到碰到第一個’\0’位置,并輸出’\0’之前的全部字元。不會因為buffer.buf的定義大小而停止讀取,此時發生溢出。(此種方式容易發生溢出攻擊)
Buffer.buf發生溢出,前八個字元被讀取到buffer.buf内,剩下的依舊被gets()函數一同讀取,順位被讀取到記憶體位址中。故buffer.others讀取剩下的全部字元,包括最後的’\n’字元,并作為輸出buffer.others的結束符。
- gdb調試跟蹤:
- fgets()函數調試
未輸入資料時,buffer.buf的内容有’\0’填充
輸入1234567890後,讀取1234567到buffer.buf前七個位元組,最後一個位元組被’\0’填充
并且沒有溢出。剩餘資料,留待下次讀取
下次讀取890’\n’ 共四個字元,最後由’\0’作為結束符。
- gets()函數調試
輸入1234567890後,函數讀取的資料如下
發生溢出,資料超出BUF_SIZE的部分被讀取到buffer.others中。發生溢出
不會因為’\n’作為結束符,将其作為‘普通’字元,進行輸出