天天看点

关于对段错误问题的分析及处理

关于对段错误问题的分析及处理

1、段错误是什么

就是指访问的内存超出了系统所给这个程序的内存空间,一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了。

2、常见的问题

1)总是试图往内存为0的地址处写新的数据

2)内存越界(数组越界,变量类型不一致等)

3、如何有效的避免

<1>定义了指针后记得初始化,在使用的时候记得判断是否为NULL

<2>在使用数组的时候是否被初始化,数组下标是否越界,数组元素是否存在等

<3>在变量处理的时候变量的格式控制是否合理等

4、常用的调试方法

1)用gdb来调试,在遇到段错误时,内核会生成core文件,但是一般我们是无法直接看到这个文件的。

第一、首先我们需要让隐藏的core文件显现出来,通过ulimt -a (资源使用情况)core文件大小缺省为0,则无法将内核的信息装载进去

第二、使用ulimit -c 1024 手动给该文件调整大小(1024)

第三、然后再运行一次,就可以将内核的信息装载进core文件

第四、ls当前目录,一般是程序运行的目录下,就可以看到带文件进程号的core文件

第五、选择gdb调试、gdb + 可执行文件 + core文件 运行,注意,一般在gcc 时最好需要加上-g方便显示错误的信息,否则只会显示错误的地址

第六、直接运行 run(r), 收到了来自操作系统的SIGSEGV信号 意味着我们试图去访问一段非法的内存

第七、 backtrace(= bt):显示栈信息

定位到#0 会告诉你是哪个【我的 free_root 】函数当中发生了问题

2)通过反汇编的方式,objdump

第一、首先先执行可执行文件输出提示段错误,然后执行dmesg命令,在输出信息的最底下找到最近一次发生段错误的记录。(Dmesg + | grep +目标)

注:dmesg的主要作用是 用来显示内核环缓冲区(kernel-ring buffer)内容,内核将各种消息存放在这里

segfault at 315020feb0 ip 00436eaa sp 7ffd604532a0 error 7 in StatisticDB[400000+2dd000]

发生段错误的地址为:315020feb0

而指令指针地址为:00436eaa

指令指针寄存器IP的作用是用于控制程序中指令的执行顺序

第二、生成反汇编代码。通过执行objdump -d + 执行的程序 > 文件 并且输出重定向到指定的文件下,方便对文件的内容进行操作,通过上面发生段错误的指令指针寄存器地址快速找出发生错误的程序位置,然后对程序进行分析排查问题会定位到哪个函数内发生了错误,然后再对照代码分析就可以了(我的 是free_root函数中发生错误)

以上就是我总结的关于对段错误的两种分析的解决方式,有什么不足之处欢迎交流学习

继续阅读