GDB内存转储

 

文章出处:http://blog.163.com/xuelei1@yeah/blog/static/116467133201110254919338/

    core dump,通常译作内存转储,core之所以译作内存,而不是核心,纯属“著名”的历史原因,因为早期的内存有一个叫磁芯(magnectic core)的东西。内存转储会在磁盘中产生一个文件,是某个进程在转储时刻的内存影响及寄存器等信息。内存转储通常发生在进程执行了有致命错误的指令时,常见的就是著了名的Segmentation fault,即段错误,而导致段错误的就是C/C++编程中经常发生的内存非法访问。内存转储操作由操作系统内核进行。当然,内存转储还可以是用户主动发起请求,内核执行转储

    内存转储对于程序调试是至关重要的。利用内存转储文件(core files)对程序进行调试是一种异步的静态调试,所谓异步是指异常发生与调试不是在同一时刻,所谓静态指的是core files保存的只是转储时刻进程的内存状态。

    比如,一个长期运行的服务程序,我们不知道哪里有bug,该bug何时被触发,这种情况下,利用异常发生时的转储文件就可以在一定程度上定位出异常发生的原因。

    另外,对于非致命性错误,比如死锁或者死循环,进程不会自动结束,通常内核也不会主动杀掉这种进程,这时用户就可以请求内核将该进程进行内存转储,以此来查看进程的运行状态(比如各进程的堆栈)。

使能/生成内核转储

    ulimit -c 命令可以查看和控制转储文件允许的生成大小,如果你的程序发生了致命错误却没有被转储,很可能是该值被设为零了。ulimit -c CORESIZE可以将core files所允许的最大值设为CORESIZE,ulimit -c unlimited取消对core files大小的限制,内核为尽量多的转储进程的内存。

    异常发生时,内核会根据设定大小生成转储文件。

    手动生成转储文件有两种方法,使用gdb attach到目标进程执行generate-core-file(缩写为gcore),但由于attach到进程会导致进程在较长时间内挂起,对某些程序(比如网络程序)会造成不必要的影响,这时使用随gdb一起发布的gcore命令就比较合适了,且更加方便。

1 2 3 4 5 
$ pgrep -l foobar 12345    foobar $ gdb gdb> attach 12345 gdb> gcore
1 
$ gcore `pidof foobar`


格式符 说明
%% %
%p pid
%u uid
%g gid
%s 引发core dump的信号编号
%t 转储时间
%h 主机名
%e 可执行文件名
%c ulimit -c

此外,kernel.core_pattern还可以加上路径前缀,用以是core文件转储到特定的目录。

使用gdb调试内存转储文件

    使用gdb可以方便的查看转储文件,同时还需要进程的可执行文件(包含进程的虚地址空间),若想调试时能够查看源代码,编译可执行文件时需要加上-g调试选项,同时还要有源代码可用(注意:编译器的-g选项并没有把源代码包含到可执行文件中)。

1 
$ gdb EXECUTABLE -c COREFILE

或者

1 
$ gdb EXECUTABLE COREFILE

或者

1 2 
$ gdb EXECUTABLE gdb> core COREFILES
    另外,向前面说的, 利用转储文件进行调试属于静态调试,gdb的很多命令是“无法使用”的,比如 i proc mapping。当然更无法进行单步调试

    另外,转储文件为ELF格式文件,可以使用objdump/readelf等工具查看,但相比动态库、可执行文件等其他ELF二进制文件,它包含的信息是有限的。


 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值