Chinaunix首页 | 论坛 | 博客
  • 博客访问: 693705
  • 博文数量: 90
  • 博客积分: 3225
  • 博客等级: 少校
  • 技术积分: 1200
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-20 11:04
个人简介

菩提本无树,明镜变非台 本来无一物,何处惹尘埃

文章分类

全部博文(90)

文章存档

2015年(1)

2014年(12)

2013年(15)

2012年(31)

2011年(8)

2010年(23)

分类: LINUX

2011-03-11 16:50:24


目录

简介 
 core dump
文件是记录某个进程在某个时间点上的镜像。该时间点可能是程序的执行出错时候,也可能是某个随机的时间点。

1 测试环境

  1. $uname -a
  2. linux dev 2.4.21-9.30AXsmp #1 SMP Wed May 26 23:37:09 EDT 2004 i686 i686 i386 GNU/Linux

2 查看默认limit

  1. $ ulimit -a
  2. core file size (blocks, -c) 0
  3. data seg size (kbytes, -d) unlimited
  4. file size (blocks, -f) unlimited
  5. max locked memory (kbytes, -l) 4
  6. max memory size (kbytes, -m) unlimited
  7. open files (-n) 2048
  8. pipe size (512 bytes, -p) 8
  9. stack size (kbytes, -s) 10240
  10. cpu time (seconds, -t) unlimited
  11. max user processes (-u) 7168
  12. virtual memory (kbytes, -v) unlimited
从结果可以看到默认的core file size为0 ,也就是说,默认是不会产生core文件。

3 设置core dump文件大小

可以通过以下命令来设置core文件大小
  1. $ ulimit -c 1024
  2. $ ulimit -a
  3. core file size (blocks, -c) 1024
  4. data seg size (kbytes, -d) unlimited
  5. file size (blocks, -f) unlimited
  6. max locked memory (kbytes, -l) 4
  7. max memory size (kbytes, -m) unlimited
  8. open files (-n) 2048
  9. pipe size (512 bytes, -p) 8
  10. stack size (kbytes, -s) 10240
  11. cpu time (seconds, -t) unlimited
  12. max user processes (-u) 7168
  13. virtual memory (kbytes, -v) unlimited

4 设置core dump文件名

默认情况下,产生的core dump文件名为“core”。如果想设置core dump的文件名,
可以通过修改“/proc/sys/kernel/core_pattern”和“/proc/sys/kernel/core_uses_pid”文件内容来达到该目的。
设置方法如下:

  1. echo "pattern" > /proc/sys/kernel/core_pattern
  2. echo "[0|1]" > /proc/sys/kernel/core_uses_pid
其中“core_pattern”是设置core dump文件名的规则,规则如下:
  1. %%: %
  2. %p:
  3. %u:
  4. %g:
  5. %s: 导致dump的信号的数字
  6. %t: dump的时间戳
  7. %h: hostname
  8. %e: 执行文件的名称;
而“core_uses_pid”是为了向后兼容,用于设置是否在core file的末尾加上“%p”,“1”为是。
我设置的“core_pattern"内容如下:
  1. $cat /proc/sys/kernel/core_pattern
  2. core.%p
这里设置在core后面加上进程pid,通过设置“core_uses_pid”也可以达到这个效果。

5 程序异常产生core dump文件

代码如下:

  1. #include <stdio.h>
  2. #include <unistd.h>

  3. void create_dump(void)
  4. {
  5.     if ( 0 == fork() ){
  6.         char *p=0;
  7.         *p = 'O';
  8.     }
  9. }

  10. int main(int argc, const char *argv[])
  11. {
  12.     int i;
  13.     for (i = 1; i < 100; ++i) {
  14.         sleep(1);
  15.         printf("i(%03d)\n",i);
  16.         if ( 0 == i%11 )
  17.             create_dump();
  18.     }
  19.     return 0;
  20. }
这里通过“create_dump()"函数生成的子进程来产生core dump文件,这样做的好处是不会导致原先进程挂死,而且可用create_dump()来生成程序在某一时刻的镜像。
子进程是利用设置非法指针来产生异常的。
编译该代码,并执行
  1. [10:17:01 core_dump]$gcc -g main.c -o create_core
  2. [10:17:24 core_dump]$ls
  3. create_core main.c Makefile
  4. [10:17:28 core_dump]$./create_core
  5. i(001)
  6. i(002)
  7. i(003)
  8. i(004)
  9. i(005)
  10. i(006)
  11. i(007)
  12. i(008)
  13. i(009)
  14. i(010)
  15. i(011)
  16. ^C
  17. [10:17:50 core_dump]$ls
  18. core.4787 create_core main.c Makefile
  19. [10:17:51 core_dump]$
这里已经生成一个名“core.4787“的core dump文件

6 利用abort()产生core dump文件

将上一节的“create_file()"函数中的使用非法指针操作换成“abort()”就行了,代码如下:
  1. #include <stdlib.h>

  2. void create_dump(void)
  3. {
  4.         if ( 0 == fork() ){
  5. #if 0
  6.                 char *p=0;
  7.                 *p =1;
  8. #else
  9.                 abort();
  10. #endif
  11.         }
  12. }
操作方法与上一节一样。

7 利用gdb工具产生core dump文件

gdb调试工具使用“attach”可以连接指定的已运行进程,并且gdb可以对它调试的程序生成那个时刻的core dump文件。
这里写个小程序进行测试,小程序代码如下:

  1. /*main.c*/
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. int main(int argc, char **argv)
  5. {
  6.   int i=0;
  7.     while(1) {
  8.            sleep(1);
  9.            ++i;
  10.      }
  11. }
下面是具体的操作步骤:
  1. [10:52:23 demo]$gcc -g main.c -o test
  2. [10:52:34 demo]$./test &
  3. [2] 5419
  4. [10:52:37 demo]$sudo gdb
  5. GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
  6. Copyright (C) 2012 Free Software Foundation, Inc.
  7. License GPLv3+: GNU GPL version 3 or later <
  8. This is free software: you are free to change and redistribute it.
  9. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  10. and "show warranty" for details.
  11. This GDB was configured as "i686-linux-gnu".
  12. For bug reporting instructions, please see:
  13. <
  14. (gdb) attach 5419
  15. Attaching to process 5419
  16. Reading symbols from /home/jake/apps/c/src/demo/test...done.
  17. Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
  18. Loaded symbols for /lib/i386-linux-gnu/libc.so.6
  19. Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
  20. Loaded symbols for /lib/ld-linux.so.2
  21. 0xb77b3424 in __kernel_vsyscall ()
  22. (gdb) gcore core.5419
  23. Saved corefile core.5419
  24. (gdb) q
  25. A debugging session is active.

  26. Inferior 1 [process 5419] will be detached.

  27. Quit anyway? (y or n) y
  28. Detaching from program: /home/jake/apps/c/src/demo/test, process 5419
  29. [10:53:57 demo]$ls
  30. core.5419 main.c test
这里可以看到已经生成“core.5419"文件,这里gdb操作需要root权限!

8 利用gcore工具产生core dump文件

gcore工具可直接对指定的进程生成那个时间点的core dump文件,其实gcore工具是对第7节的gdb使用操作进行的封装。使用格式如下:
  1. gcore [-o filename] pid
其中“-o filename"指定生成core dump文件的名字,不指定的话,使用系统配置的。
这里使用第7节的小程序进行测试,具体操作如下:
  1. [10:35:31 demo]$./test &
  2. [1] 5042
  3. [10:35:36 demo]$sudo gcore 5042
  4. 0xb77b6424 in __kernel_vsyscall ()
  5. Saved corefile core.5042
  6. [10:35:47 demo]$ls
  7. core.5042 main.c test
  8. [10:35:49 demo]$
gcore工具需要使用root权限执行,可以看到这里生成一个“core.5042"文件。

9 使用gdb分析core dump文件

这里选择对第5节产生的core dump文件进行分析。其具体操作如下:

点击(此处)折叠或打开

  1. [11:02:14 core_dump]$gdb ./core_dump
  2. GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
  3. Copyright (C) 2012 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  7. and "show warranty" for details.
  8. This GDB was configured as "i686-linux-gnu".
  9. For bug reporting instructions, please see:
  10. <..
  11. Reading symbols from /home/jake/apps/c/src/core_dump/core_dump...done.
  12. (gdb) core-file core.5575
  13. [New LWP 5575]
  14. warning: Can't read pathname for load map: Input/output error.
  15. Core was generated by `./core_dump'.
  16. Program terminated with signal 11, Segmentation fault.
  17. #0 0x0804845d in create_dump () at main.c:10
  18. 10 *p =1;
  19. (gdb) bt
  20. #0 0x0804845d in create_dump () at main.c:10
  21. #1 0x080484c4 in main (argc=1, argv=0xbfb89ac4) at main.c:24
  22. (gdb) frame 1
  23. #1 0x080484c4 in main (argc=1, argv=0xbfb89ac4) at main.c:24
  24. 24 create_dump();
  25. (gdb) print i
  26. $1 = 11
  27. (gdb) l 10
  28. 5 void create_dump(void)
  29. 6 {
  30. 7 if ( 0 == fork() ){
  31. 8 #if 1
  32. 9 char *p=0;
  33. 10 *p =1;
在第18行可以看到,程序执行到“*p=1"时出现错误,这时通过第27行的操作,打印出附近的代码,发现原来是对0地址的赋值而引起的异常。
同时通过第25行“print i"打印,发现确实"i=11"时执行的操作。

注:转载本文时请注明出自:add358.blog.chinaunix.net


阅读(1470) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~