首页 > 代码库 > 实验一:实验环境配置与使用
实验一:实验环境配置与使用
一、实验目标:
熟悉Linux上C程序的编译和调试工具,包括以下内容:
1. 了解Linux操作系统及其常用命令
2. 掌握编译工具gcc的基本用法
3. 掌握使用gdb进行程序调试
二、实验环境与工件
1.个人电脑
2. Fedora 13 Linux 操作系统
3. gcc
4. gdb
三、实验内容与步骤
1.根据实验一:实验环境配置与使用.ppt熟悉Linux基本操作(P.1 – P.28),然后根据以下过程创建用户:用户名为学生名称加学号,如赖丹辉,学号2013150040,则该用户名为Laidanhui_2013150040。按照1.1~1.3完成并截图,截图需要有运行的命令及其结果。另外:后面的题目必须在该新建用户下完成。
实验步骤:
1.1.首先切换为超级用户
在终端环境下,$su
1.2. 参考以下命令创建新用户, 设置新建用户的密码,注意:只有设置了密码才能激活用户,否则无法以该用户身份登录
#useradd (your name)
#passwd (your password)
1.3. 注销当前用户,并以新建的用户身份登录,登录后运行 $ whoami,并进行截图;
2.新建用户主目录下创建子目录:gdbdebug, 并进入gdbdebug 子目录。将过程和结果截图。
先切换到超级用户,然后使用mkdir命令在home/XuXianyuan_2015150147目录下创建gdbdebug子目录,再使用ls显示该目录下内容,黄色部分结果表示创建成功。
进入gdbdebug目录下:
进入成功。
3.使用vi编辑以下两个文件并编译和运行,截图
3.1.编辑reverse.h
最后在最后使用:wq保存并退出
在gdbdebug目录下使用ls命令:(黄色标注部分表示reverse.h文件创建成功。)
3.2.编辑reverse.c
3.3.按以下步骤编译,如有警告信息,请修改代码至无警告信息
$gcc –Wall reverse.c –o reverse:生成的所有警告信息如下图所示:
分析相应的警告信息:
第一条:隐式声明函数‘strlen’,很明显没有包含相应头文件,故只需在reverse.c中 添加头文件<string.h>即可。
第二条:格式 ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[1024]’,这个警告是说输入格式不对,将scanf(“%s”,&str)中的&去掉。
第三条:在有返回值的函数中,控制流程到达函数尾,这个警告的意思是函数声明存在返回值但是并未返回,将reverse函数返回声明为void,并且为main函数最后面添加return 0语句
(在linux下,main函数声明为void会产生警告如下图:)
所有警告处理完以后,结果截图如下图所示:
3.4.运行程序
$./reverse
此时发现输入的abcdefg,但是最终结果是aecdcba,结果是与预期结果gfedcba完全不同的。
4.按照以下过程调试并修正reverse.c,请参考过程截图。
4.1. 编译时加入调试信息
$gcc -g reverse.c -o reverse1
4.2. 启用GDB调试
使用file 命令,装入想要调试的可执行程序 reverse1;
4.3. 键入list,查看源代码并根据行号/函数名设置断点
断点设置总体如下:
接下来是运行:
4.4. 观察变量值,并作分析,推测错误
分析如下:
图中所标示的1,2,3分别表示经过断点以后,输入的字符串变化情况;
在第一步中,由于只是执行了c=*str+i,也就是说字符串不会发生变化,对比图片所给出的变化情况,可以得知这个结果是正确的,也就是说第一步不存在错误;
在第二步中,执行代码*(str+1)=*str+len-i-1,按照正常情况,字符串第一个字符应该被最后一个字符所替代,但结果却是第二个字符被最后一个字符替代,所以很可能在这里出错了;
在第三步中,执行c=*str+i;也即是最后一个字符串被变量c所指代的字符替代,由第一步,可以知道,最后一个结果应该是被第一个字符所替代,对比图片的结果,结果是正确的,也即是说该代码不存在错误;
4.5. 修正程序并运行
在上述步骤的分析中,有如下修改方案:将第二步中的*(str+1)=*str+len-i-1修改为*(str+i)=*str+len-i-1
修改完成后尝试运行reverse.c:
结果是:结果更加离谱-。-
没办法,接下来重新进入gdb调试:
4.6. 观察变量值,并作分析,推测错误
调试结果如下:
分析过程同4.4,这里直接给出最终分析结果:1-4步结果是符合实际的,而在第5步中,hbcdefga本应该是转化为hgcdefga,也即是倒数第二个赋值给第二个,但是结果却是hncdefga,这个n来的有点莫名其妙,但在仔细分析代码后发现,代码竟然是*(str+i)=*str+len-i-1,omg!后面的表达式竟然没加大括号!-.-
如果不加大括号后面的表达式的意思是*str=‘h’,然后len=8,i=1,就有‘h’+8-1-1----->‘n’,转化为字符‘n’;
恩,知道哪里错了以后,先在reverse.c相应位置加上大括号(截图如下)
然后再来运行一次。
4.7. 修正程序并运行
显然,实验结果是正确无误的。
至此,“计算机系统概论”这门课的第一次实验算是总体完成了,另外,在学习过程中难免会有疏漏,如果发现了本文中的某些错误,欢迎提出指正ヽ(???)?(???)?
实验一:实验环境配置与使用