linux C 段错误一览

来源:互联网 发布:卓有成效的管理者知乎 编辑:程序博客网 时间:2024/05/29 11:43
发生段错误的情况(程序出现的错误):
  1. 下面总结
发生段错误的运行时的现象特征:
  1. 接收到系统传来的SIGSEGV信号,在默认情况下(不设置用户的信号处理函数),系统终止运行程序。
发生段错误的调试时的现象特征:
  1. 直接在出现断错误的语句停止运行,并给出Segmentation fault提示。
  2. 如果某个函数中发生访问越界,很可能并不立即产生段错误,而在函数返回时却产生段错误。

使用工具:
  1. GDB:主要命令:bt
  2. dmesg+nm 链接(这方法带商榷,nm是二进制查看)
  3. core dump所产生的core文件
  4. 利用段错误引起的SIGSEGV信号,来设置信号处理函数(signal(SIGSEGV,handler)),一旦触发,就启动gdb调试
  5. 利用backtrace和objdump进行分析 链接
    1. backtrace(3),可以获取程序的堆栈信息并在程序中利用(获取栈内容),还有其余族函数,man;同样是设置信号处理函数
    2. objdump命令,是查看可执行文件的构成的gcc工具

出错原因:
导致段错误的直接原因
- 解除引用一个包含非法值
- 解除引用一个空指针(常常由函数返回,并未经检查就使用)访问NULL的过程链接
- 在未得到正确的权限时进行访问。例如,试图往一个只读的文本段储存值就会引发段错误。
- 用完了栈或者堆空间(虚拟内存虽然巨大,但也有可能使用殆尽)

在编程中以下几类做法容易导致段错误,基本上是错误地使用指针引起的。
1)访问系统数据区,尤其是往系统保护的内存地址写数据最常见就是给一个指针以0地址。
2)内存越界(数组越界,变量类型不一致等):访问到不属于你的内存区域。

引申解析:

关于调试时使用printf(最多最常用的方式)
切记调试信息要输出到错误输出,因为错误输出默认不缓存,标准输出是有缓存的,程序崩溃可能导致缓存数据没有输出,所以建议调试信息都输出到错误输出。使用最好使用能够定向输出的printf组函数,如fprintf。

关于core文件:
在出现段错误的情况下,没有出现core文件,这很可能是系统为了减少垃圾文件的数量,禁止了core文件的生成(系统可能将core文件的大小限制在512K,也可能是0呢)
xiaosuo@gentux test $ ulimit -c//检测当前系统的core文件大小
0
xiaosuo@gentux test $ ulimit -c 1000//设置系统的core文件大小为1000
xiaosuo@gentux test $ ulimit -c
1000
xiaosuo@gentux test $ ./a.out
段错误 (core dumped)
xiaosuo@gentux test $ ls
a.out core d.c f.c g.c pango.c test_iconv.c test_regex.c
//接着就可以调试core文件
xiaosuo@gentux test $ gdb ./a.out core
//下面会输出core文件信息

参考博文:
  1. 用gdb调试程序笔记: 以段错误(Segmental fault)为例 链接
  2. 段错误 百科链接
  3. What are segmentation faults (segfaults), and how can I identify what's causing them?链接
0 0
原创粉丝点击