本节将讲解一个程序调试实例。首先编写一个程序,在程序运行时,发现结果与预想结果有些不同,然后用gdb工具进行调试,通过单步运行和对变量的查看,查找出程序的错误。
【实例 4.2】 编写一个程序,要求程序运行时可以显示下面的结果。
很明显,这个程序是通过两次循环与一次判断得到的。程序中需要定义 3 个变量。下面用这个思路来编写这个程序。
①打开一个终端,在终端中输入“vim”命令,打开VIM。
②在VIM中按“I”键,进入插入模式,然后在VIM中输入代码,如实例代码 4.2 所示。
实例代码 4.2 显示指定格式文本
【代码解析】代码使用两个循环语句实现格式化输出。第7 行的代码最后有一个“;”号,导致循环体是空的,会直接跳过执行第15 行的输出换行。后面用gdb工具调试来找出这个错误。
③在VIM中按“Esc”键,返回普通模式,然后输入下面的命令,保存这个文件。
④输入“:q”命令退出VIM。很容易发现,在第2 个循环的后面多了一个分号。
本节将对上一节编写的程序进行编译和运行。在运行程序时,会发现程序有错误。
①在终端中输入下面的命令,编译这个程序。
②程序可以正常编译通过。输入下面的命令,运行这个程序。
③程序的显示结果是 4 个空行,并没有按照预想的要求输出结果。
④输入下面的命令,对这个程序进行编译。在编译时加入-g参数,为gdb调试做准备。
⑤这时,程序可以正常编译通过。输出的文件是test.debug,这个文件中加入了文件调试需要的信息。
本节将讲述使用gdb对上一节编写的程序进行调试,查找出程序中的错误。
①在终端中输入“gdb”命令,进入gdb,显示的结果如下所示。
②导入文件。在gdb中输入下面的命令。
③这时显示的结果如下所示,表明已经成功加载了这个文件。
④查看文件。在终端中输入下面的命令。
⑤显示的文件查看结果如下所示。
⑥在程序中加入断点。从显示的代码可知,需要在第6、11~13 行加入断点。在gdb中输入下面的命令。
⑦gdb显示的添加断点的结果如下所示。
⑧输入下面的命令,运行这个程序。
⑨运行到第1 个断点位置,显示的结果如下所示。
⑩输入“step”命令,程序运行一步,结果如下所示。
这说明程序已经进入了for循环。这时输入下面的命令,查看i的值。
显示的结果如下所示。
输入“step”命令,显示的结果如下所示。
再输入“step”命令,显示的结果如下所示。
这表明,在进行j的for循环时,没有反复执行循环体。这时输入“step”命令,显示的结果如下所示。
这表明,程序正常地进行了i的for循环。这是第二次执行for循环。
输入“step”命令,显示的结果如下所示。
这表明,程序执行到for循环。再次输入“step”命令,显示的结果如下所示。
输入“step”命令,显示的结果如下所示。
输入“step”命令,显示的结果如下所示。
这说明,程序正常地进行了i的for循环,但是没有执行j的for循环。这一定是j的for循环语句有问题。这时就不难发现j的for循环后面多了一个分号。
输入“q”命令,退出gdb。
gdb有非常多的命令,输入“help”命令可以显示这些命令的帮助信息。本节将讲解gdb帮助的使用。
①在gdb中输入“help”命令,显示的帮助信息如下所示。
②上面的帮助信息显示,输入“help all”命令会输出所有的帮助信息。
③在“help”命令后面加上一个命令名称,可以显示这个命令的帮助信息。例如输入“helpfile”,显示的file命令帮助信息如下所示。