注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

onefish资料库

成功要素---耐得住孤独!

 
 
 

日志

 
 

Core Dump  

2011-03-14 03:12:15|  分类: 程序 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在 Windows 下我们已经习惯了用 Windbg 之类的工具调试 dump 文件,从而分析并排除程序运行时错误。在 Linux 下我们同样可以完成类似的工作 —— Core Dump。

我们先看看相关的设置。
$ ulimit -a  core file size       (blocks, -c) 0 data seg size        (kbytes, -d) unlimited scheduling priority          (-e) 20 file size            (blocks, -f) unlimited pending signals              (-i) 16382 max locked memory    (kbytes, -l) 64 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) unlimited virtual memory       (kbytes, -v) unlimited file locks                   (-x) unlimited

"core file size  (blocks, -c) 0" 意味着在程序崩溃时不会生成 core dump 文件,我们需要修改一下设置。如果你和我一样懒得修改配置文件,那么就输入下面这样命令吧。
$ sudo  sh -c "ulimit -c unlimited; ./test" # test 是可执行文件名。

等等…… 我们还是先准备个测试目标。
#include <stdio.h> #include <stdlib.h>  void test() {     char* s = "abc";     *s = 'x'; }  int main(int argc, char** argv) {     test();     return (EXIT_SUCCESS); }

很显然,我们在 test() 里面写了一个不该写的东东,这无疑会很严重。生成可执行文件后,执行上面的命令。
$ sudo sh -c "ulimit -c unlimited; ./test"  Segmentation fault (core dumped)
$ ls -l  total 96 -rw------- 1 root  root  167936 2010-01-06 13:30 core -rwxr-xr-x 1 yuhen yuhen   9166 2010-01-06 13:16 test

这个 core 文件就是被系统 dump 出来的,我们分析目标就是它了。
$ sudo gdb test core  GNU gdb (GDB) 7.0-ubuntu Copyright (C) 2009 Free Software Foundation, Inc.  Reading symbols from .../dist/Debug/test...done.  warning: Can't read pathname for load map: Input/output error. Reading symbols from /lib/tls/i686/cmov/libpthread.so.0... ...done. (no debugging symbols found)...done. Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0 Reading symbols from /lib/tls/i686/cmov/libc.so.6... ...done. (no debugging symbols found)...done. Loaded symbols for /lib/tls/i686/cmov/libc.so.6 Reading symbols from /lib/ld-linux.so.2... ...done. (no debugging symbols found)...done. Loaded symbols for /lib/ld-linux.so.2  Core was generated by `./test'. Program terminated with signal 11, Segmentation fault. #0  0x080483f4 in test () at main.c:16  warning: Source file is more recent than executable. 16        *s = 'x';

最后这几行提示已经告诉我们错误的原因和代码位置,接下来如何调试就是 gdb 的技巧了,可以先输入 "where" 看看调用堆栈。
(gdb) where  #0  0x080483f4 in test () at main.c:16 #1  0x08048401 in main (argc=1, argv=0xbfd53e44) at main.c:22
(gdb) p s  $1 = 0x80484d0 "abc"
(gdb) info files  Symbols from ".../dist/Debug/test". Local core dump file:  Local exec file:     `.../dist/Debug/test', file type elf32-i386.     Entry point: 0x8048330     0x08048134 - 0x08048147 is .interp     ... ...     0x08048330 - 0x080484ac is .text     0x080484ac - 0x080484c8 is .fini     0x080484c8 - 0x080484d4 is .rodata

很显然 "abc" 属于 .rodata,严禁调戏。

在程序中实现
利用 setrlimit() 函数我们可以将 "core file size" 设置成一个非 0 值,这样就可以在崩溃时自动生成 core 文件了。(可参考 bshell ulimit 命令)
  1 #include <sys/resource.h>                                                   
  2 void test() 
  3 {     
  4     char* s = "abc";
  5     *s = 'x'; 
  6 }  
  7 int main(int argc, char** argv) 
  8 {     
  9     struct rlimit res = 
 10     { 
 11         .rlim_cur = RLIM_INFINITY, 
 12         .rlim_max = RLIM_INFINITY 
 13     };     
 14     setrlimit(RLIMIT_CORE, &res);
 15     test();      
 16     return (EXIT_SUCCESS); 
 17 }

  评论这张
 
阅读(64)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017