zoukankan      html  css  js  c++  java
  • Linux coredump

    前面写过通过注册信号处理函数定位SEGV问题。其实Linux coredump机制也是比较好的debug手段。

    进程由于某种异常或者bug导致在运行过程中异常退出或者中止,有时会产生一个叫做core的文件。在此文件中包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息。

    core文件一般在以下几种情况下产生:

    1,内存访问越界

      a) 由于使用错误的下标,导致数组访问越界。

      b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符。

      c) 使用strcpy, strcat, sprintf, strcmp,strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。

    2,多线程程序使用了线程不安全的函数。

    3,多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成coredump

    4,非法指针

      a) 使用空指针

      b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump。

     5,堆栈溢出

    不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。

    默认情况下一般系统不会产生core文件。

    如果ulimit -c的结果为0,不会产生core文件。可以用ulimit -c filesize,filesize 是生成文件的大小,以blocks为单位,1个block为512bytes。可以将其设置unlimited(ulimit -c unlimited)那么core文件大小不受限制。可以将命令加到/etc/profile中。也可以在程序中用setrlimit函数来设置。

    我们还可以设置core文件的生成路径。

    通过echo /mnt/hgfs/share/test/core.%e.%p > /proc/sys/kernel/core_pattern

    生成的core文件名字为“core.程序文件名.进程ID”

    可以在代码中打开core_pattern文件,将路径名字写到文件中,也可以将修改路径的命令加到rc.local中。

    下面以一个简单的sample来演示怎么用core文件定位问题。

    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/time.h>
    #include <sys/resource.h>
    #include <fcntl.h>

    void func()
    {

      printf("func! ");
      int *p = NULL;
      *p = 8;
      printf("func! %d ",*p);
    }

    int main(void)
    {

      const char *path = "/mnt/hgfs/share/test/core.%e.%p";
      int fd = open("/proc/sys/kernel/core_pattern", O_WRONLY);
      if (fd < 0)
      {
        printf("open fail, errno:%d, %s ", errno, strerror(errno));
        return -1;
      }
      write(fd, path, strlen(path));
      close(fd);
      #if 1
      struct rlimit rl = {RLIM_INFINITY, RLIM_INFINITY};
      if (0 != setrlimit(RLIMIT_CORE, &rl))
      {
        printf("setrlimit fail, errno:%d, %s ", errno, strerror(errno));
        return -1;
      }
      #endif

      func();
      return 0;
    }

    gcc -g coredump.c -o coredump

    运行程序后在指定的路径下生成了core文件。

    成功将路径写到/proc/sys/kernel/core_pattern

    我们可以看到core文件其实也是一种ELF格式。

     

    通过gdb来查看core文件。可以看出在coredump.c的第13行发生了SEGV

  • 相关阅读:
    HTML5手机APP开发入(5)
    HTML5手机APP开发入(4)
    HTML5手机APP开发入(3)
    HTML5手机APP开发入门(2)
    五一干货来袭!开源Moon.Orm标准版发布!
    你不知道的HttpHandler相关知识
    我们就专心做一件事情---数据处理框架
    jQuery Mobile案例,最近用Moon.Web和Moon.Orm做了一套系统
    谈谈字符编码的问题
    一起玩玩面试题(第一关)---五道题估计你要挂四道
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6184686.html
Copyright © 2011-2022 走看看