今天调试一个用户态的程序,折腾了好长时间,最终还是搞定了,错误的原因很简单,memcpy的时候出界了,导致segfault。这个程序在测试用例的环境下,一直没有问题,但是与其他程序集成之后,就经常出现segfault的错误,并且是在内核dmesg中打印出来的。所以,错误的原因很难查找。后来通过逐一排查、分析,不断缩小故障范围,最后找到了错误的原因。实际上,故障的原因很简单,就是memcpy的时候数据拷多了,导致虚拟内存的地址出界,出现了segfault的严重错误。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
坐下来细想一下,实际上我们很多的程序bug都是这样的内存操作错误,特别是内核程序,很多莫名其妙的问题都是内存操作错误导致的。前一段时间,我一直在调试一个快照内核程序,在读写快照卷的时候总是出现内核kernel panic,而且内核调用栈打印出来的信息都与自己的程序无关,都是些Linux任务调度相关函数,所以,一开始以为是锁之类的问题,是不是在不可睡眠的地方进行了睡眠?导致Linux系统无法调度?但是,经过一段时间的调试表明,问题的根源不在于锁,不是锁问题导致了系统的panic。后来才考虑到,有可能快照程序非法修改了其他程序的内存,导致其他程序出现故障,表现出锁的问题。顺着这样的思路,最终找到了问题的根源,的确是我快照程序非法修改了其他程序的内存单元,是我链表释放的时候,出现了一个非法指针,并且后继程序可能会对该非法指针进行访问,该非法指针的内存单元正好被其他程序使用,所以导致其他程序运行出错,出现kernel panic。这是一个典型的内存操作错误(空指针错误)问题。
我估计,在软件开发过程中,由于内存操作导致的错误数量占所有错误数量的50%以上,内核软件的这个比例会更高,可能达到70%以上,这只是我个人的初略估计。但是内存问题的确程序开发过程中经常遇到的问题,很多重大问题的“病根”也就在内存操作这一块。所以,在程序设计、开发过程中,需要始终对内存操作多留一个心眼,特别在内核程序中保持高度的警惕性,那么我们的程序BUG数量就会减少很多,程序的健壮性将会大大提高。
文章评论(0条评论)
登录后参与讨论