C语言编程中如何避免Crash问题?
1,努力做到这几点,不要觉得麻烦
近几年处理的Kernel Panic, Kernel Oops, 应用程序Crash(signal 11, Signal 10, Signal 6, Signal 4) 不下没有100也有80,但是产品中的各种Crash问题仍然层出不穷,有感而发。解决问题是我的职责所在,但年复一年地解决Crash问题,我也快Crash了。提高解决问题的效率和能力,并不能提高产品质量,总结要点、整理错误类型,避免错误才是正道。通过对工程代码的分析,有以下老生常谈的警示:
- 对传入的参数进行合法性判断:指针是否为空,buffer及其length是否在范围内,变量是否超过最大取值范围等。
- 对指针判空再使用:assert(ptr);之后再使用这个指针。
- 废弃strcpy没有长度控制的接口,用strncpy等有长度控制的接口替代:strcpy不小心就会造成越界,越界后如果dst变量在堆上就踩堆,dst变量在栈上就会踩栈。
- strncpy/memcpy的size控制:你传入的size是不是正确的?对于字符串来说就是(sizeof(dst) - 0x1),对于binary来说,就是sizeof(typeof(dst))。
- 动态内存释放后置空:野指针也会有人使用。
以上几点做到,无论写什么功能,至少90%的crash都没了。
模块编译过程中,GCC的warning都清除掉了吗?如果没有打开-Wall -Werror, 解决所有的编译错误,不要说写出了达到工程交付质量的代码。
GCC选项的-fstack-protecter-strong打开跑过测试吗?-fmudflap这么好的东西为什么不用?实在不行用valgrind也可以检查堆内存的越界。
2,解决Crash的方法
(这回儿2020/12/29 22:23还在编译中,一会儿就要去解core文件了,有空仔细补上)
解决Kernel Panic的方法:通过addr2line、objdump、gdb等方法找到引起crash的C代码行,分析流程,分析寄存器、栈,复现问题,找到root cause,解决问题。
看看这个经典案例,看不懂留言我会讲解。
http://www.opensourceforu.com/2011/01/understanding-a-kernel-oops/
解决App Crash的方法:用gdb解core文件,分析调用栈,分析汇编。Syslog有没有记录?对照core文件分析crash前在哪个流程中。
Marty