Linux环境下的C/C++基础调试技术(2)

(GDB) r 12 5
^C
Program received signal SIGINT, Interrupt.
0x080484ff in insert (new_y=3) at insert_sort.c:45
/home/gnuhpc/MyCode/Debug/Chapter_01/insert_sort/pg_019/insert_sort.c:45:939:beg:0x80484ff
(GDB)

Linux环境下的C/C++基础调试技术

我们可以看到程序停止在第49行。我们看一下num_y现在的值:

(GDB) p num_y
$1 = 1

这里的$1指的是你要GDB告诉你的第一个变量。找到了这个地方后,我们看看在num_y=1时都发生了什么,我们在insert函数(第27行)设置断点(你也可以直接使用break insert在这个函数的入口设置断点),并且设置GDB在断点1处(你可以通过info break命令查看断点)只当num_y==1时才停止:

(GDB) b 27
Breakpoint 1 at 0x80484a1: file insert_sort.c, line 27.
(GDB) condition 1 num_y==1
(GDB) 

上述命令也可以使用break if合一:

(GDB) break 27 if num_y==1

然后再运行程序,随后用n单步调试发现我们跳到了该函数的出口处:

Linux环境下的C/C++基础调试技术

此时我们看看num_y的值,以便查看到底这个for循环执行的情况。

(GDB) p num_y
$2 = 0

此时的情况是我们进入这个函数时num_y为1,但是现在num_y为0,在中间这个变量被改变了。现在你知道Bug就在30-36行间。同时,通过单步调试你发现31-33行被跳过了,34、35行为注释,那么Bug就在第30或第36行间了。

我们现在仔细看这两行就能得出结论了:30行有个典型的if判断条件写成赋值的错误,致命的是这个变量是全局变量,直接导致49行的for循环变量一直被重置。我们修改后重新编译(可以另开一个编辑器,不用退出ddd),然后再运行

(GDB) r 12 5
5
0

虽然没有了死循环,但是结果还是不对的。

请注意,初始的时候数组y是空的,在#49进行第一次循环时,y[0]应该为12,在第二个循环中,程序应该挪动12为5腾出位置插入,但是此时这个结果看上去是5取代了12。

此时单步调试进入for循环,#37看y[0]的值,的确是12。我们执行到scoot_over函数时,根据自顶向下准则我们单步跳过,继续执行到#41,看看结果对错再决定是不是要单步进入scoot_over函数:

Linux环境下的C/C++基础调试技术

我们发现12根本就没有被移动,说明scoot_over函数有问题,我们去掉insert函数入口的断点,在scoot_over入口处设置断点,当num_y=1的时候终止:b scoot_over if num_y==1。进一步单步调试后发现这个#23的for循环就没有执行。

(GDB) p jj
$12 = 0
(GDB) p k
$13 = 0

我们看到是因为没有满足for循环条件而不能进入循环。在这里12应该从y[0]移动到y[1],那么我们确定是循环的初始化错误,应该为k = num_y,将这个地方修改后编译运行,程序出现段错误。我们清空所有的断点,然后在

(GDB) r

Program received signal SIGSEGV, Segmentation fault.
0x08048483 in scoot_over (jj=0) at insert_sort.c:24
(GDB)

这里指出在24行出现seg fault,那么要么k超过了数组界限,要么k-1为负的。打印一下k的值,我们就发现:

(GDB) p k
$14 = 992
(GDB)

远远超过k应该有的值。查看num_y 为1,说明在处理第二个要排序的数时出错,再打印jj值,发现为0,就发现我们的for循环k++应该改为k—。

编译运行,发现ok。但是运行多个数据就又出错了:

(GDB) r 12 5 19 22 6 1
1
5
6
12
0
0

Program exited with code 06.
(GDB)

我们看到结果中从19开始的排序都有问题,我们在for (j = 0; j < num_y; j++)  这一行行设置断点,条件为new_y==19的时候:

(GDB) break 36 if new_y==19
Breakpoint 10 at 0x80484b1: file insert_sort.c, line 36.
(GDB)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwsjgf.html