前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GDB调试艺术:处理奔溃和隐藏逻辑bug

GDB调试艺术:处理奔溃和隐藏逻辑bug

作者头像
望月从良
发布2021-07-08 10:46:14
5700
发布2021-07-08 10:46:14
举报
文章被收录于专栏:Coding迪斯尼

程序奔溃是一件令人头疼之事,最要命的是那种运行很久后莫名其妙奔溃的情形。GDB调试器对处理奔溃很有用,当程序运行在GDB的管控下时,如果出现奔溃,那么它会直接指出奔溃的代码行,这使得奔溃查找变得非常高效,例如上次出现的段错误,如果我们使用GDB再次运行,它会停留在奔溃的代码行:

也就是说y[k]=y[k-1]这行导致奔溃,对于数组访问行程的奔溃而言,通常情况下就是数组元素读取越界,显然导致该原因的只能是下标k的值出现问题,于是我们使用print语句确认一下涉及到的几个变量值:

代码语言:javascript
复制
print k

上面指令运行后在我的环境下打印出976,显然这个值已经远远超出了数组y的元素个数,因此应该是k值出错了,仔细审查就能发现,其实它是在for循环中k++这条语句有问题,其实它应该是k—,修改后程序可以正常运行,于是我们可以输入一系列测试用例再次检验程序正确性,我们使用测试案例如下:

代码语言:javascript
复制
./insert_sort  12 5 17 23 7 1

运行后得到结果为:1 5 7 12 0 0, 数值17以后的元素没有插入到数组中,因此我们再次对这个问题进行调试,由于是数值17有问题,因此在变量new_y等于17时,insert函数的执行可能会出问题,于是设置断点如下:

代码语言:javascript
复制
break insert if num_y == 17

然后执行run 12 5 17 23 7 1, GDB会在num_y等于17时停止,首先我们看看此时数组y内的排序情况,因此执行print y,可以看到5, 12 正确的插入了数组y,于是我们可以通过next单步调试来看看它如何处理数值17,根据多次next可以发现,在insert函数中for (j = 0; j < num_y; j++)循环运行几次后根本没有执行scoot_over函数,也就是说代码没有执行 y[j] = new_y;这条元素插入操作。从代码上看我们能发现问题,那就是循环里只判断new_y小于当前数组元素的情况,如果大于数组里面元素,那么什么操作都不进行,因此代码需要处理这种情形,于是代码修改如下:

代码语言:javascript
复制
 if (new_y < y[j]) {
            scoot_over(j);
            y[j] = new_y;
            return;
        }
        else {
            y[num_y] = new_y;
        }

改完之后再次运行结果就正常了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档