core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIGSEGV信号,然后就会core dump)
在程序运行的过程中,有的时候我们会遇到Segment fault(段错误)这样的错误。这种看起来比较困难,因为没有任何的栈、trace信息输出。该种类型的错误往往与指针操作相关。往往可以通过这样的方式进行定位。
一 造成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 堆栈溢出.不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
二配置操作系统使其产生core文件
首先通过ulimit命令查看一下系统是否配置支持了dump core的功能。通过ulimit -c或ulimit -a,可以查看core file大小的配置情况,如果为0,则表示系统关闭了dump core。可以通过ulimit -c unlimited来打开。若发生了段错误,但没有core dump,是由于系统禁止core文件的生成。
解决方法:
$ulimit -c unlimited (只对当前shell进程有效)
或在~/.bashrc 的最后加入:ulimit -c unlimited(一劳永逸)
# ulimit -c
0
$ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
三用gdb查看core文件
发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.
gdb [exec file] [core file]
如:gdb ./test test.core
四样例
1. 空指针
样例:
#include <stdio.h>
int main(void)
{
printf("hello world! dump core for set value to NULL pointer/n");
*(char *)0 = 0;
return 0;
}
# gcc -g test.c -o test
# ./test
hello world! dump core for set value to NULL pointer
Segmentation fault
/× Get segmentation fault, but there is no core dump. The reason is that the system configure core file size to zero ×/
# ls
test test.c
/* Set core file size to unlimited*/
# ulimit -c unlimited
# ./test
hello world! dump core for set value to NULL pointer
Segmentation fault (core dumped)
/* Get core dump after change core file size.*/
# ls
core.5581 test test.c
/* gdb todebug core dump*/
# gdb test core.5581
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib64/tls/libc.so.6...done.
Loaded symbols for /lib64/tls/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
#0 0x000000000040048b in main () at test.c:6
warning: Source file is more recent than executable.
6 *(char *)0 = 0;
(gdb) bt
#0 0x000000000040048b in main () at test.c:6
2. 栈溢出。
有关栈溢出的程序,请参见:一个测试栈大小的小程序
http://blog.163.com/huang_bp/blog/static/12311983720099150746901/edit/
# gcc -g test.c -o test -lpthread
# ls
test test.c
# ./test
...
Segmentation fault (core dumped)
# ls
core.5616 test test.c
# gdb test core.5616
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib64/tls/libpthread.so.0...done.
Loaded symbols for /lib64/tls/libpthread.so.0
Reading symbols from /lib64/tls/libc.so.6...done.
Loaded symbols for /lib64/tls/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
#0 0x0000002a957c051e in vfprintf () from /lib64/tls/libc.so.6
(gdb) list
13
14 buffer[0]=i;
15 test(s);
16 }
17
18 int main()
19 {
20 pthread_t p;
21
22 pthread_create(&p, NULL, &test, NULL);
对于栈溢出的segment fault没有第一个定位方便,需要分析代码才能判断出原因。
相关推荐
GDB常用命令,调试core文件最常用的
讲述常用gdb命令,以及讲述如何使用gdb调试程序崩溃后产生的core dump文件,让您在linux下开发更轻松
GDB调试GDB调试GDB调试GDB调试GDB调试 GDB调试GDB调试GDB调试GDB调试GDB调试
用GDB调试程序 用GDB调试程序 用GDB调试程序 用GDB调试程序 用GDB调试程序 用GDB调试程序
GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹及使用实例GDB调试精粹...
程序运行到异常的地方,这时会在执行文件的当前目录产生core文件,嵌入式gdb调试core
GDB调试程序[陈皓] GDB调试工具指南 两个pdf文件
陈浩-用GDB调试程序(整理有书签).pdf+守望的个人博客-GDB调试指南(整理有书签).pdf
GDB之在线调试与Coredump分析,通过gdb一步步分析coredump文件。
GDB调试打印STL PROTOBUF,只要放到.gdbinit文件中就可以直接打印MAP LIST VECTOR SET DEQUEUE等等STL容器里装的东西了。还有PROTOBUF里装的东西也可以打印出来,调试时看PB协议很方便。
gdb调试器的使用gdb调试器的使用gdb调试器的使用gdb调试器的使用gdb调试器的使用
主要介绍了Linux下如何使用gdb调试core文件,帮助大家更好的理解和学习Linux,感兴趣的朋友可以了解下
Linux下怎么产生core dump文件及GDB怎么调试core.pptx Linux下怎么产生core dump文件及GDB怎么调试core.pptx
是学习嵌入式的很好的资料哦!里面详细介绍了怎样用gdb调试程序,是嵌入式程序调试入门必备的资料!
-g:在可执行文件中加入源码信息,比如:可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件都嵌入到可执行文件中,而是在调试时必须保证gdb能找到源文件。这些调试信息包括行号、变量的类型和...
用GDB调试程序 用GDB调试程序 用GDB调试程序 用GDB调试程序 用GDB调试程序
非常详细的介绍 Linux下gdb调试工具指南
GDB调试中文手册。GDB调试命令详述,完整的中文手册。
使用GDB调试,英文版。对于从事 Linux C/C++ 后台开发的读者来说,GDB 调试是需要熟练掌握的一项技能
gdb调试命令及实例精选gdb调试命令及实例精选gdb调试命令及实例精选