扩展阅读
  • linux c/c++ IP字符串转换成可比较大小的数字
  • 在win分区上安装linux和独立分区安装linux有什么区别?可以同时安装吗?(两个linux系统)
  • linux哪个版本好?linux操作系统版本详细介绍及选择方案推荐
  • 在虚拟机上安装的linux上,能像真的linux系统一样开发linux程序么?
  • secureCRT下Linux终端汉字乱码解决方法
  • 我重装window后,把linux的引导区覆盖了,进不了linux怎么办?急啊,望热心的人帮助 (现在有linux的盘)
  • Linux c字符串中不可打印字符转换成16进制
  • 红旗Linux主机可以通过127.0.0.1访问,但如何是连网的Win2000机器通过Linux的IP去访问Linux
  • Linux常用命令介绍:更改所属用户群组或档案属性
  • 安装vmware软件,不用再安装linux系统,就可以模拟linux系统了,然后可以在其上学习一下LINUX下的基本操作 了?
  • linux命令大全详细分类介绍及常用linux命令文档手册下载
  • 我重装window后,把linux的引导区覆盖了,进不了linux怎么办?急啊,望热心的人帮助 (现在没有linux的盘,只有DOS启动盘)
  • Linux Kernel 'sctp_v6_xmit()'函数信息泄露漏洞
  • 如何让win2000和linux共存。我装好WIN2000,再装LINUX7.0,但LILO只能找到LINUX,不能引导WIN2000
  • Linux c++虚函数(virtual function)简单用法示例代码
  • 在windows中的VMware装了个linux,主板有两个串口,能做windows和linux的串口通信测试么,怎么测试这两个串口在linux是有效
  • Docker官方镜像将会使用Alpine Linux替换Ubuntu
  • 我们网站的服务器从windows2000迁往linux,ASP程序继续使用,可是我连LINUX的皮毛都不了解,大家告诉我LINUX下怎么建网站??
  • Linux下chmod命令详细介绍及用法举例
  • 中文Linux与西文Linus分别哪一个版是权威?I认为是:中科软的白旗Linux与西文的绿帽子Linux!大家的看法呢?
  • linux僵尸(zombie)进程介绍及清除
  • Windows2000和Linux双操作系统,Linux系统有问题,我直接把Linux分区删除后,Windows2000进不去了,怎么办???
  •  
    当前位置:  编程语言>c/c++

    Linux下c/c++开发之程序崩溃(Segment fault)时内核转储文件(core dump)生成设置方法

     
        发布时间:2014-2-26  


        本文导语:  Linux下c/c++开发之程序崩溃(Segment fault)时内核转储文件(core dump)生成设置方法 Linux下c/c++开发程序崩溃(Segment fault)通常都是指针错误引起的.以下是我们详细的对Linux core dump的调试技术进行的介绍: Linux core dump简介有的程...

     linux下c/c++开发程序崩溃(segment fault)时内核转储文件(core dump)生成设置方法

     Linux下c/c++开发程序崩溃(Segment fault)通常都是指针错误引起的.以下是我们详细的对Linux core dump的调试技术进行的介绍:

    Linux core dump简介

    有的程序可以通过编译, 但在运行时会出现Segment fault(段错误). 这通常都是指针错误引起的.但这不像编译错误一样会提示到文件->行, 而是没有任何信息, 使得我们的调试变得困难起来.

     Segment fault)时内核转储文件(core dump)作用

    (1) 内核转储的最大好处是能够保存问题发生时的状态

    (2) 只要有可执行文件和内核转储,就可以知道进程当时的状态。

    (3) 只要获取内核转储,那么即使没有复现环境,也能调试。

      Linux core dump gdb

    有一种办法是, 我们用gdb的step, 一步一步寻找.

    这放在短小的代码中是可行的, 但要让你step一个上万行的代码, 我想你会从此厌恶程序员这个名字, 而把他叫做调试员.

    我们还有更好的办法, 这就是core file.

      Linux core dump ulimit

    如果想让系统在信号中断造成的错误时产生core文件, 我们需要在shell中按如下设置:

    #设置core大小为无限

    ulimit -c unlimited

    #设置文件大小为无限

    ulimit unlimited

    这些需要有root权限, 在ubuntu下每次重新打开中断都需要重新输入上面的第一条命令, 来设置core大小为无限.

      Linux core dump用gdb查看core文件

    下面我们可以在发生运行时信号引起的错误时发生core dump了.

    发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.

    gdb [exec file] [core file]

    如:

    gdb ./test test.core

    在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行.

      System Dump和Core Dump的区别

    1) 系统Dump(System Dump)

    所有开放式操作系统,都存在系统DUMP问题。

    产生原因:

    由于系统关键/核心进程,产生严重的无法恢复的错误,为了避免系统相关资源受到更大损害,操作系统都会强行停止运行,并将当前内存中的各种结构,核心进程出错位置及其代码状态,保存下来,以便以后分析。最常见的原因是指令走飞,或者缓冲区溢出,或者内存访问越界。走飞就是说代码流有问题,导致执行到某一步指令混乱,跳转到一些不属于它的指令位置去执行一些莫名其妙的东西(没人知道那些地方本来是代码还是数据,而且是不是正确的代码开始位置),或者调用到不属于此进程的内存空间。写过C程序及汇编程序的人士,对这些现象应当是很清楚的。

    系统DUMP生成过程的特点:

    在生成DUMP过程中,为了避免过多的操作结构,导致问题所在位置正好也在生成DUMP过程所涉及的资源中,造成DUMP不能正常生成,操作系统都用尽量简单的代码来完成,所以避开了一切复杂的管理结构,如文件系统LVM等等,所以这就是为什么几乎所有开放系统,都要求DUMP设备空间物理连续的——不用定位一个个数据块,从DUMP设备开头一直写直到完成,这个过程可以只用BIOS级别的操作就可以。这也是为什么在企业级UNIX普遍使用LVM的现状下,DUMP设备只可能是裸设备而不可能是文件系统文件,而且[b]只[/b]用作DUMP的设备,做 LVM镜像是无用的——系统此时根本没有LVM操作,它不会管什么镜像不镜像,就用第一份连续写下去。

    所以UNIX系统也不例外,它会将DUMP写到一个裸设或磁带设备。在重启的时候,如果设置的DUMP转存目录(文件系统中的目录)有足够空间,它将会转存成一个文件系统文件,缺省情况下,[b]对于AIX来说是/var/adm/ras/下的vmcore*这样的文件,对于HPUX来说是 /var/adm/crash下的目录及文件。[/b]

    当然,也可以选择将其转存到磁带设备。

    会造成系统DUMP的原因主要是:

    系统补丁级别不一致或缺少)系统内核扩展BUG(例如Oracle就会安装系统内核扩展))驱动程序有 BUG(因为设备驱动程序一般是工作在内核级别的),等等。所以一旦经常发生类似的系统DUMP,可以考虑将系统补丁包打到最新并一致化)升级微码)升级设备驱动程序(包括FC多路冗余软件))升级安装了内核扩展的软件的补丁包等等。

    2) 进程Core Dump

    进程Core Dump产生的技术原因,基本等同于系统DUMP,就是说从程序原理上来说是基本一致的。

    但进程是运行在低一级的优先级上(此优先级不同于系统中对进程定义的优先级,而是指CPU代码指令的优先级),被操作系统所控制,所以操作系统可以在一个进程出问题时,不影响其他进程的情况下,中止此进程的运行,并将相关环境保存下来,这就是core dump文件,可供分析。

    如果进程是用高级语言编写并编译的,且用户有源程序,那么可以通过在编译时带上诊断用符号表(所有高级语言编译程序都有这种功能),通过系统提供的分析工具,加上core文件,能够分析到哪一个源程序语句造成的问题,进而比较容易地修正问题,当然,要做到这样,除非一开始就带上了符号表进行编译,否则只能重新编译程序,并重新运行程序,重现错误,才能显示出源程序出错位置。

    如果用户没有源程序,那么只能分析到汇编指令的级别,难于查找问题所在并作出修正,所以这种情况下就不必多费心了,找到出问题的地方也没有办法。

    进程Core Dump的时候,操作系统会将进程异常终止掉并释放其占用的资源,不可能对系统本身的运行造成危害。这是与系统DUMP根本区别的一点,系统DUMP产生时,一定伴随着系统崩溃和停机,进程Core Dump时,只会造成相应的进程被终止,系统本身不可能崩溃。当然如果此进程与其他进程有关联,其他进程也会受到影响,至于后果是什么,就看相关进程对这种异常情况(与自己相关的进程突然终止)的处理机制是什么了,没有一概的定论。


      内核转储文件(core dump)永久生效的办法

    永久生效的办法是:

    #vi /etc/profile 然后,在profile中添加:

    ulimit -c 1073741824

    (但是,若将产生的转储文件大小大于该数字时,将不会产生转储文件)

    或者

    ulimit -c unlimited

    这样重启机器后生效了。 或者, 使用source命令使之马上生效。

    #source /etc/profile

    指定内核转储的文件名和目录

       缺省情况下,内核在coredump时所产生的core文件放在与该程序相同的目录中,并且文件名固定为core。很显然,如果有多个程序产生core文件,或者同一个程序多次崩溃,就会重复覆盖同一个core文件。

      我们可以通过修改kernel参数,指定内核转储所生成的core文件的路径和文件名。

    可以通过在/etc/sysctl.conf文件中,对sysctl变量kernel.core_pattern的设置。

    #vi /etc/sysctl.conf 然后,在sysctl.conf文件中添加下面两句话:

    kernel.core_pattern = /var/core/core_%e_%p

    kernel.core_uses_pid = 0

    保存后退出

    需要说明的是, /proc/sys/kernel/core_uses_pid。如果这个文件的内容被配置成1,即使core_pattern中没有设置%p,最后生成的core dump文件名仍会加上进程ID。


    这里%e, %p分别表示:

    %c 转储文件的大小上限

    %e 所dump的文件名

    %g 所dump的进程的实际组ID

    %h 主机名

    %p 所dump的进程PID

    %s 导致本次coredump的信号

    %t 转储时刻(由1970年1月1日起计的秒数)

    %u 所dump进程的实际用户ID

    可以使用以下命令,使修改结果马上生效。


    #sysctl –p /etc/sysctl.conf


    请在/var目录下先建立core文件夹,然后执行a.out程序,就会在/var/core/下产生以指定格式命名的内核转储文件。查看转储文件的情况:

    #ls /var/core

    core_a.out_2834


    Linux下c/c++开发之程序崩溃(Segment fault)时内核转储文件(coredump)生成举例说明


    例子的源代码


    #include <stdio.h>

    int main(void)

    {

    int *a = NULL;


    *a = 0x1;


    return 0;

    }


    把以上源代码,写成一个a.c文件后,编译a.c文件产生一个a.out的可执行文件:

    #gcc -g a.c -o a.out

    修改a.out文件的权限后,执行它:

    #./a.out

    就会显示:

    Segmentation fault(core dump)

    这表示在当前目录下, 已经生成了a.out对应的内核转储文件。

    注意:后面带有(core dump), 才说明转储文件成功生成了。

    #file core*

    core:elf 64-bit lsb core file x86-64, version 1(sysv), svr4-style, from './a.out'

    coredump: utf-8 unicode c program text


    要用GDB调试内核转储文件,应该使用以下方式启动GDB:

    #gdb -c ./*.core ./a.out

    GNU gdb (GDB) 7.1-Ubuntu

    ...

    Core was generated by './a.out'.

    Program terminated with signal 11, Segmentation fault.

    #0 0x00000000004004dc in main() at a.c:6

    6 *a =0x1;

    a.c的第6行收到了11号信号。用GDB的list命令可以查看附近的源代码。

    (gdb) l 5

    1            #include <stdio.h>

    2      


    3            int main(void)

    4            {

    5                   int *a = NULL;

    6                   *a = 0x1;

    7                   return 0;

    8            }

    这里默认都是当前目录,也可以给core 和a.out 指定路径。


    相关文章推荐:
  • linux c下利用srand和rand函数生成随机字符串
  • Linux下如何生成桌面图标?
  • Linux下c基于openssl生成MD5的函数
  • linux 下,doxygen生成的html文件中文注释为乱码,请高手指教!
  • linux下利用(cat,strings,head,sed)命令生成随机字符串
  • 关于Linux下生成运行日志 的C函数
  • linux c 生成随机数srand函数和rand函数介绍及代码示例
  • 高手帮忙啊!linux中用arm-linux-gcc编译生成的二进制文件怎么复制到开发板里?
  • Linux gcov 无法生成.gcda文件
  • Linux生成的.a文件可以直接用在windows上吗?
  • Linux新手,怎么清除configure之后生成的文件?
  • linux myeclipse hibernate 反向工程无法生成 hbm.xml文件
  • 编译生成.link后缀扩展名文件命令 linux
  • 在linux下,如何生成 debug 和 release 版本的代码?
  • 同一个开发包,为什么在linux下生成的动态库比windows上大这么多?
  • linux FC5下用程序生成的文件中,中文变成问号,怎么解决?
  • linux 编译的时候,如何与.a静态库做链接生成.elf文件?
  • linux 生成静态库的时候怎么连接别的静态库
  • 安装red hat linux9.0时如何生成BOOTSECT.LIN文件?
  • 关于linux下生成so文件的问题,请教高手
  • 请问linux服务端如何生成网页的缩略图?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3