什么是段错误?

      一旦一个程序发生了越界访问,cpu 就会产生相应的保护,于是 segmentation fault 就出现了,其实所谓的段错误就是访问了不可访问的内存,该内存要么不存在,要么该进程不具备访问的权限。

段错误的原因

  • 非关联化一个空指针,非关联化一个空指针总是会导致一个段错误。而野指针就不一定会产生错误。
  • 试图访问一个不存在的内存地址(在进程的地址空间)
  • 试图访问内存的程序没有权利(如内核结构流程上下文)
  • 试图写入只读存储器(如代码段)

常用命令

  • dmesg 可以在应用程序崩溃时,显示内存中保存的相关信息。如下所示,通过 dmesg 命令可以查看发生段错误的程序名称、引起段错误发生的内存地址、指令指针地址、堆栈指针地址、错误代码、错误原因等。
  • 使用 ldd 命令查看二进制程序的共享链接库依赖,包括库的名称、起始地址,这样可以确定段错误到底是发生在了自己的程序中还是依赖的共享库中。
  • 使用 nm 命令列出二进制文件中符号表,包括符号地址、符号类型、符号名等。这样可以帮助定位在哪里发生了段错误。

printf方法

      使用printf进行调试的时候,我们可以使用printf方法,为了方便使用这种方法,可以使用条件编译指令 #define DEBUG 和 #endif 把 printf 函数包起来。这样在程序编译时,如果加上 -DDEBUG 参数就可以查看调试信息;否则不加上参数就不会显示调试信息。

注意事项

1)出现段错误时,首先应该想到段错误的定义,从它出发考虑引发错误的原因。
2)在使用指针时,定义了指针后记得初始化指针,在使用的时候记得判断是否为 NULL
3)在使用数组时,注意数组是否被初始化,数组下标是否越界,数组元素是否存在等
4)在访问变量,注意变量所占地址空间是否已经被程序释放掉
5)在处理变量时,注意变量的格式控制是否合理等