首页 > 代码库 > 实验一:实验环境配置与使用

实验一:实验环境配置与使用

一、实验目标:

 

熟悉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.   修正程序并运行

技术分享

显然,实验结果是正确无误的。

 

至此,“计算机系统概论”这门课的第一次实验算是总体完成了,另外,在学习过程中难免会有疏漏,如果发现了本文中的某些错误,欢迎提出指正ヽ(???)?(???)? 

技术分享

实验一:实验环境配置与使用