Linux 程序CoreDump -- GDB调试方法汇总

1.coredump介绍及产生原因

  1. 什么是coredump:
    程序由于各种异常或者bug导致在运行过程中异常退出或者中止, 此时系统会生成core文件, 其中包含程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等.

  2. 程序coredump原因:
    <1>.内存访问越界
    <2>.多线程程序使用了线程不安全的函数
    <3>.多线程读写的数据未加锁保护
    <4>.非法指针
    <5>.堆栈溢出


2.GDB调试coredump步骤

  1. 设置coreDump文件大小, 默认是0:
    首先在当前会话执行命令:ulimit –c,若为0,则不会产生对应的coredump,需要进行修改和设置:
    ulimit -c 1024(字节)
    ulimit -c unlimited (可以产生coredump且不受大小限制)
  2. 程序gcc/g++编译时加 “-g”参数.
  3. 经过上述两步, 再运行程序coredump后, 会在当前目录生成core.xxx文件.
  4. 开始调试, 执行命令:gdb [可执行文件] [core.xxx文件]
  5. 输入命令: bt或back trace, 查看调用堆栈(会显示每个调用帧及帧号)
  6. 输入命令: f或frame [num], 查看对应堆栈帧
  7. 输入命令: args:查看函数参数; locals:查看本地变量

3.GDB断点调试命令

  1. gdb [可执行文件] : 开始调试
  2. run: 重新运行程序
  3. break/b [fileName] : [lineNum]/[funcName] :设置断点
  4. continue/c: 运行至断点处, 相当于VS中的F5
  5. next: 过程调试, 相当于VS中的F10
  6. step: 单步调试, 相当于VS中的F11
  7. print [variableName]: 查看变量值
  8. list/l : 显示当前代码段
  9. info break/b: 查看所有断点
  10. delete/d [breakNum]: 删除对应断点
  11. clear: 删除所有断点

以上是基础命令, 更多操作详见链接


4. GDB调试守护进程

使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止。那么该如何调试子进程呢?
上网查了下, 一共有3种方法, 这里采用attach的方法:
其它方法详见链接

  1. ps -ef :查看所需调试的子进程号, pidNum
  2. 运行gdb, 并执行命令:(gdb)attach [pidNum]
  3. 附加到该子进程后,一个新的问题是:子进程一直在运行,attach上去后都不知道运行到哪里了.
    一个办法是,在要调试的子进程初始代码中,比如main函数开始处,加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继续执行下去。:
    至于这段代码所采用的条件,看你的偏好了。比如我们可以检查一个指定的环境变量的值,或者检查一个特定的文件存不存在。以文件为例,其形式可以如下:

    
    #include <unistd.h>//linux下 access()函数头文件
    
    void debug_wait(char* fileName)
    {
    while(1)
    {
        if (!access(fileName, 0))//access检查文件,存在返回0
            睡眠一段时间;
        else
            break;
    }
    }

    当attach到进程后,在该段代码之后设上断点,再把该文件删除就OK了。当然你也可以采用其他的条件或形式,只要这个条件可以设置/检测即可。
    Attach进程方法还是很方便的,它能够应付各种各样复杂的进程系统,比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的就是加入一小段代码。

  4. 接下来就可以继续打断点调试了

  5. info threads:当前运行线程, 可以使用thread [num] 切换线程

  6. set scheduler-locking off|on, on 可以保证断点只让当前线程命中, 默认是off(所有线程都可命中断点)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值