天天看點

fgets()與gets()函數的差別,并用gdb工具調試驗證

fgets()與gets()函數的差別,并用gdb工具調試驗證

  南昌大學工程實驗報告

學生姓名:   秦琦琛         學    号:   8000116xxx          專業班級:    軟工1611班       

實驗類型:■ 驗證 □ 綜合 □ 設計 □ 創新   實驗日期: 2018、10、8  實驗成績:           

一、實驗目的

熟悉linux程式設計環境,學會使用gcc、gdb和編寫工程管理檔案makefile。

  • 實驗内容
  1. 将書中例題2-2和2-3調出結果,并編寫對應的帶參數的makefile檔案。
  • 實驗要求

1.必須編制測試樣例,将程式中兩函數的差別展現。送出代碼截圖和運作結果截圖并附文字說明情況。

2.使用gdb工具,進行動态調試。檢視在輸入測試用例時,程式執行的情況。

3.實驗報告必須用南昌大學統一的實驗報告格式模闆制作,報告以sybg1.doc命名送出。

四、主要實驗步驟

1.建立如下檔案

fgets()與gets()函數的差別,并用gdb工具調試驗證

如圖所示代碼,為本實驗頭檔案my.h。包含函數的定義以及必要頭檔案聲明

fgets()與gets()函數的差別,并用gdb工具調試驗證
fgets()與gets()函數的差別,并用gdb工具調試驗證
fgets()與gets()函數的差別,并用gdb工具調試驗證

2.使用makefile管理檔案進行編譯

fgets()與gets()函數的差別,并用gdb工具調試驗證

3.調試: 使用gdb指令調試,調試之前首先用gcc –g指令來生成調試資訊,否則調試失敗:

五、實驗資料及處理結果

1.測試樣例分析:兩函數的差別

(1)

fgets()與gets()函數的差別,并用gdb工具調試驗證

使用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()與gets()函數的差別,并用gdb工具調試驗證

使用fgets()函數:

       輸入:123456             輸出:123456\n

分析:此種情景,同上示例第二次讀取

(3)

fgets()與gets()函數的差別,并用gdb工具調試驗證

使用gets()函數:

       輸入:123456789123456789      輸出:123456789123456789

       溢出:9123456789

分析:gets()函數以’\n’作為結束符。當如上輸入時,gets()函數從首位讀取,直到碰到第一個’\0’位置,并輸出’\0’之前的全部字元。不會因為buffer.buf的定義大小而停止讀取,此時發生溢出。(此種方式容易發生溢出攻擊)

       Buffer.buf發生溢出,前八個字元被讀取到buffer.buf内,剩下的依舊被gets()函數一同讀取,順位被讀取到記憶體位址中。故buffer.others讀取剩下的全部字元,包括最後的’\n’字元,并作為輸出buffer.others的結束符。

  1. gdb調試跟蹤:
  1. fgets()函數調試
    fgets()與gets()函數的差別,并用gdb工具調試驗證

未輸入資料時,buffer.buf的内容有’\0’填充

fgets()與gets()函數的差別,并用gdb工具調試驗證

輸入1234567890後,讀取1234567到buffer.buf前七個位元組,最後一個位元組被’\0’填充

并且沒有溢出。剩餘資料,留待下次讀取

fgets()與gets()函數的差別,并用gdb工具調試驗證

下次讀取890’\n’ 共四個字元,最後由’\0’作為結束符。

  1. gets()函數調試

輸入1234567890後,函數讀取的資料如下

fgets()與gets()函數的差別,并用gdb工具調試驗證

發生溢出,資料超出BUF_SIZE的部分被讀取到buffer.others中。發生溢出

不會因為’\n’作為結束符,将其作為‘普通’字元,進行輸出

繼續閱讀