天天看点

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’作为结束符,将其作为‘普通’字符,进行输出

继续阅读