一、实验目标:
熟悉Linux上C程序的编译和调试工具,包括以下内容:
了解Linux操作系统及其常用命令
掌握编译工具gcc的基本用法
掌握使用gdb进行程序调试
二、实验环境与工件
个人电脑
Fedora 13 Linux 操作系统
gcc
gdb
三、实验内容与步骤
根据实验一:实验环境配置与使用.ppt熟悉Linux基本。按照1.1~1.3完成并截图,截图需要有运行的命令及其结果。另外:后面的题目必须在该新建用户下完成。(30分)
实验步骤:
1.1. 首先切换为超级用户
输入su进入超级用户:
发现出现Authentication failure,可能是密码忘记了,此时,可以使用sudo passwd root来给root重设密码:
如上,则密码已经成功的重设了。
1.2. 参考以下命令创建新用户, 设置新建用户的密码,注意:只有设置了密码才能激活用户,否则无法以该用户身份登录
①首先查询当前用户:
②创建新用户dongyunhao_2019284073
在终端中输入sudo adduser dongyunhao_2019284073
并输入超级用户密码与新创建账户密码后,再输入一些账户信息最后确认即可完成创建。
1.3. 注销当前用户,并以新建的用户身份登录,登录后运行 $ whoami,并进行截图;
①点击左上角log out->switch user并选择新创建的用户,输入密码后即可登录。
②查看当前用户,在终端中输入whoami即可查看当前用户名
新建用户主目录下创建子目录:gdbdebug, 并进入gdbdebug 子目录。将过程和结果截图。(10分)
①输入命令:sudo mkdir gdbdebug并运行
可以发现报错,提示“not in the sudoers file”这说明当前用户(新创建的用户)不具有sudo的权限,因此我们需要给当前用户权限。此时需要进入root进行操作
②进入root:
输入su后再输入visudo进入权限管理操作文件页面。并给当前用户dongyunhao_2019284073添加权限后退出即可。
③重新创建文件夹:
此时再使用sudo mkdir gdbdebug命令,即可成功创建
④查看创建的文件夹:
输入ls命令查看文件夹
⑤进入文件夹:
输入 cd gdbdebug 即可进入文件夹
使用vi编辑以下两个文件并编译和运行,截图(30分)
3.1. 编辑reverse.h
①创建reverse.h文件:
输入vi reverse.h并运行
②编辑reverse.h
进入编辑页面后先输入i以切换到文字输入模式,然后输入如下代码
输入完成后按“esc”结束输入,并键入“:wq”对代码进行保存
3.2. 编辑reverse.c
①显示代码高亮与行号:
在上一步骤的代码编写中,发现在vim进行编辑时代码没有代码高亮也没有行号。因此可以打开对应的设置。
首先更新vim,输入命令apt install vim
将自动更新下载vim,完成下载后,进入vim的设置文件。输入vim ~/.vimrc,并输入如下命令:
保存并退出后即可看到代码已经有了代码高亮和行号。
②创建并编写reverse.c
与上一部分中创建的代码相同,输入vi reverse.c并运行。并在其中写入代码。
代码编写完成后输入“wq:”进行保存并退出。
3.3. 按以下步骤编译,如有警告信息,请修改代码至无警告信息
$gcc –Wall reverse.c –o reverse
①输入命令并执行
发现未安装gcc,则手动进行安装
②安装gcc
首先切换到root并输入代码进行安装
弹出的提示信息中选择Yes。
等待安装完毕即可
③编译并运行
再次输入命令进行编译。可以观察到如下几个信息:
a. strlen函数未声明。又注意到提示说中含有对strlen函数的定义,故可以在代码中添加此头文件
b.在main函数中%s的输入格式不应存在char *格式,但第二个参数中存在char *格式,因此需要去掉取地址符
c.int型返回值函数没有返回值。在函数末尾补一个return 1即可
进入代码进行修改,修改完成后保存即可。
④重新进行编译
可以看到重新编译后警告信息消失了
3.4. 运行程序
输入代码 ./reverse进行运行
虽然程序执行了,但输出是错误的,因此我们需要进行debug并对代码进行修改调试。
按照以下过程调试并修正reverse.c,请参考过程截图。(30分)
4.1. 编译时加入调试信息
$gcc -g reverse.c -o reverse1
4.2. 启用GDB调试
4.3. 键入list,查看源代码并根据行号/函数名设置断点(断点位置仅供参考,不需雷同)
①输入list对代码进行查看
②添加并查看断点:
由于函数中第16,17,18行发生的操作比较容易发生问题,故在此添加断点。
完成断点添加后,可以输入info break对断点信息进行查看
③开始调试
输入run进行调试
4.4. 观察变量值,并作分析,推测错误(过程仅供参考,不需雷同)
开始运行,在程序运行中可以输入c进行跨越一个断点的运行
从程序运行间可以看到,当第一次对字符数组操作时,第一个“M”本应被替换成“G”缺被替换成了“T”通过分析代码可知,代码的本意应该是通过指针交换第一个与最后一个字符,而实际上却是发生了偏移。这是因为,每次的指针应该是*(str+i)而不是*str+i,在C语言运行时,将先执行指针符号,再执行加法,因此需将两处都加上括号。
4.5. 修正程序并运行
通过上面的分析,对代码进行修改如下:
修改完成后重新进行编译并运行。
结果正确,程序运行无误
四、实验结果
如上图,程序运行无误,最后也输出了正确的结果。
五、实验总结与体会
本次实验进行的比较顺利,但也遇到了一些问题:
Ubuntu上Linux系统与Windows系统有一样的地方也有区别,例如对文件读写时可能会因为权限问题造成不能读写。此时需要进入root对相关权限文件进行修改。在权限文件中添加用户之后便可以顺利对文件进行读写操作了。
在编写代码过程中没有代码高亮与行号。我自己下载了新的vim,并通过修改vim的配置文件最终得到解决。
编写C程序代码时要注意程序运行的优先级。本次实验中就是因为忽略了指针运算符(*)会在加法运算符(+)前执行导致程序错误。不过最后通过debug问题得到解决
实验体会:
通过本次实验,我了解了Linux操作系统及其常用命令,掌握了编译工具gcc的一些基本用法,也掌握了使用gdb进行程序调试是步骤。我也自己编写了代码,最初代码并不能得到想要的输出,通过调试,最终使代码正常运行。在实验过程中遇到了一些问题,最终也都通过上网查阅资料分析原因而解决。