设置ulimit 调试 segment fault
今天调试程序,总是遇到segment fault,由于的多线程程序,gdb调试很麻烦,非常不爽,但是Bug还总是在哪里需要解决啊。
只得想办法。网上说可以生成core文件,再用gdb调试core,至少可以定位到哪里出错。于是Google。
segment fault产生的原因主要是与指针操作相关。
《GDB调试core文件样例(如何定位Segment fault) 》详细介绍了相关错误原因
View Code
一 造成segment fault,产生core dump的可能原因
1.内存访问越界
a) 由于使用错误的下标,导致数组访问越界
b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符
c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。
应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。
2 多线程程序使用了线程不安全的函数。
3 多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump
4 非法指针
a) 使用空指针
b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,
否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。
这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump.
5 堆栈溢出.不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
有了错误原因,接下去就是如何做了。
在各种Linux/GNU的发行版本中,一般core生成是没有打开的,需要通过ulimit命令来打开相关的选项。
ulimite -a 命令输出如下
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 4095
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 4095
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
可以看到 core block 为0
现在用 ulimite -c 1024 打开core生成选项。(在Debian下并不需要用sudo,sudo反而找不到命令)。
编译程序的时候添加-g选项,生成调试信息。
生成a.out
运行 ./a.out 生成段错误文件core.13764
再调试即可。
gdb ./a.out core.13764
运行到错误处,在gdb中输入
bt可以定位到代码是哪一行出错的。
接下来,就是逐步这样迭代了。
PS:良好的代码风格与编程技巧是减少无谓错误的良方,切记,切记。