core dump文件分析和调试
core介绍
当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。
core文件生成
core文件的生成开关和大小限制
- 使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。
- 使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。
- 使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。若ulimit -c unlimited,则表示core文件的大小不受限制。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件。在调试此core文件的时候,gdb会提示错误。
在bash中使用ulimit -c unlimited
修改core开关,仅对当前shell生效,若希望永久生效,
core文件生成路径和文件名
/proc/sys/kernel/core_uses_pid可以控制产生的core文件的文件名中是否添加pid作为扩展,如果添加则文件内容为1,否则为0
/proc/sys/kernel/core_pattern可以设置格式化的core文件保存位置或文件名,比如原来文件内容是core-%e
可以这样修改:
echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
将会控制所产生的core文件会存放到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
如果core_uses_pid这个文件的内容被配置成1,那么即使core_pattern中没有设置%p,最后生成的core dump文件名仍会加上进程ID。
注意linux的内核参数信息都存在内存中,因此可以用过命令直接修改,并直接生效。但是当系统reboot后,之前设置的参数值就会丢失,而系统每次启动时都会去/etc/sysctl.conf文件中读取内核参数。
因此可以将参数写在这个配置文件中,如:
kernel.core_pattern = %e.core.%p
并保存退出,执行下面指令使其生效
sysctl -p
在我的linux机器中,core_pattern的配置为|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %e
, |
表示使用管道,将core文件重定向给后边的程序处理,这里是交由systemd-coredump程序处理。要获取core文件则应该使用coredumpctl
命令获取core文件(需要sudo权限)。
这里我使用a.out产生一个core文件。首先使用sudo coredumpctl list | grep a.out
获取core文件的信息。显示结果如下:
Wed 2018-09-19 17:22:39 CST 54666 1100 0 11 * /polestar_build/home/dev/test/core/a.out
从结果中知道PID是54666,可以使用sudo coredumpctl dump 54666 -o a.dump
,将core文件dump到a.dump中。
core文件格式
core文件是一个标准的ELF格式的文件,使用readelf
工具可以对core文件的属性进行检查。如下所示,core文件的TYPE显示是CORE (Core file)
。
:~/test/core> readelf -h a.dump
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: CORE (Core file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 64 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 36
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0
gdb加载core文件
使用gdb加载core文件的命令为gdb -c core_file_name
,也可以再启动gdb后使用命令core core_file_name
在gdb中随时加载core文件。
在没有加载可执行程序以前,仅仅可以使用gdb对core文件内的内容进行检视,包括寄存器的值,以及内存分页(mappings),调用栈内存等信息。所以还需要加载可执行程序,结合执行文件和core文件分析。加载方法是在bash命令行使用gdb exe_file
,也可以在启动gdb后使用命令file exe_file
随时加载文件。
有点可执行文件不包含符号表,加载文件后会提示no debugging symbols found
, 如果有符号文件,可以使用命令"file exe_file.sym`读取符号表。
当可执行文件和core文件都加载完成后,就可以对案发现场进行验尸了,
设置sharedlibrary搜索路径
如果程序需要的动态链接库在对应的路径,则gdb可以搜索加载到so文件。如果需要加载的so放在其他目录,比如,将所有依赖的so放在了.libs目录下,就需要设置链接库搜索路径。可以使用set sysroot
和set solib-search-path
这两个命令设置so的搜索路径。需要注意的是这两个命令必须在加载core文件前使用。
下边是一个例子。第二行表示so的搜索路径包括/lib
,/usr/lib
和./
三个目录,gdb会尝试在这三个目录中搜索依赖的so文件。
(gdb) set sysroot /no/such/file
(gdb) set solib-search-path /lib:/usr/lib:./
(gdb) file Framwork.out #加载执行程序
(gdb) core core-1537131595-162728-14957-10 #加载core文件
(gdb) info sharedlibrary #查看已经加载的动态链接库
- set sysroot 与 set solib-absolute-prefix 是同一条命令,实际上,set sysroot是set solib-absolute-prefix 的别名。
- set solib-search-path设置动态库的搜索路径,该命令可设置多个搜索路径,路径之间使用“:”隔开(在linux中为冒号,DOS和Win32中为分号)。
- set solib-absolute-prefix 与 set solib-search-path 的区别:
总体上来说solib-absolute-prefix设置库的绝对路径前缀,只对绝对路径有效;而solib-search-path设置库的搜索路径,对绝对路径和相对路径均起作用。(编译器自动链接的so库多采用绝对路径)。
常用命令
- 使用bt命令可以查看程序core文件现场的调用栈。仍然使用前文中的a.out。 栈帧0明显是对空指针函数进行调用,导致内存访问出错。
:~/test/core> gdb a.out -c a.dump
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x000000000040058f in register_tm_clones ()
#2 0x00000000004005b0 in register_tm_clones ()
#3 0x0000000000000000 in ?? ()
i r
可以查看寄存器,x
可以查看内存空间,例如x/20wx $sp
查看栈顶的20个WORD。info proc mappings
查看内存映射表。
其他gdb命令参考gdb手册。
在arm程序中,由于压栈的寄存器不一致的问题,可能会导致gdb回溯调用栈失败,如下所示,此时需要结合汇编代码人工对调用栈进行回溯。参考另一篇文章。
(gdb) bt
#0 0xf72e12a0 in pthread_rwlock_timedwrlock () from /lib/libpthread-2.22.so
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
交叉环境下的core dump
例如在Arm平台上执行的程序发生了core dump, 但是希望在x86平台的linux机器上对core文件进行调试, 则需要使用交叉环境的arm-linux-gdb,而不是x86的gdb。有两个选择:
- 下载gdb源码,编译target为arm平台的arm-linux-gdb。
- 下载预编译的arm-linux-gdb。这里提供一个网上的预编译好的gcc工具链Linaro Releases.
参考链接
- http://www.cnblogs.com/hazir/p/linxu_core_dump.html
- https://blog.csdn.net/ispeller/article/details/20232089
- https://stackoverflow.com/questions/33886913/make-gdb-load-a-shared-library-from-a-specific-path
- https://blog.csdn.net/_xiao/article/details/23289971
core dump文件分析和调试的更多相关文章
- 使用GDB 追踪依赖poco的so程序,core dump文件分析.
前言 在windows 下 系统核心态程序蓝屏,会产生dump文件. 用户级程序在设置后,程序崩溃也会产生dump文件.以方便开发者用windbg进行分析. so,linux 系统也有一套这样的东东- ...
- ZT 用gdb调试core dump文件
用gdb调试core dump文件 转载自:http://blog.chinaunix.net/u2/83905/showart_2134570.html 在Unix系统下,应用程序崩溃,一般会产生c ...
- gdb调试常用实用命令和core dump文件的生成
1.生成core dump文件的方法: $ ulimit -c //查看是否为0 如果为0 $ ulimit -c unlimited 这样在程序崩溃以后会在当前目录生成一个core.xxx ...
- gdb调试常用实用命令和core dump文件的生成(转)
1.生成core dump文件的方法: $ ulimit -c //查看是否为0 如果为0 $ ulimit -c unlimited 这样在程序崩溃以后会在当前目录生成一个core.xxxx的 ...
- Ubuntu16.04下写的Qt程序,调试时没问题,运行时偶现崩溃 (需要在运行时生成core dump文件,QMAKE_CC += -g)
记录一下 Ubuntu16.04下写的Qt程序,调试时没问题,运行时偶现崩溃 需要在运行时生成core dump文件 首先在pro结尾里加入 QMAKE_CC += -g QMAKE_CXX += - ...
- Linux上Core Dump文件的形成和分析
原文: http://baidutech.blog.51cto.com/4114344/904419 Core,又称之为Core Dump文件,是Unix/Linux操作系统的一种机制,对于线上服务而 ...
- Windbg内核调试之四: Dump文件分析
Dump 文件分析很大程度上就是分析蓝屏产生的原因.这种系统级的错误算是Windows提示错误中比较严重的一种(更严重的还有启动黑屏等硬件或软件兼容性错误等等).说它是比较严重,是因为毕竟Window ...
- Core dump文件和ECFS
core dump文件 core dump核心转储文件,一些信号的处理方式,会生成一个elf格式的文件,用来分析进程崩溃情况. 总结一下,core dump核心转储文件就是将所有的vma都映射成一个e ...
- 蓝屏 Dump文件分析方法
WinDbg使用有点麻烦,还要符号表什么的.试了下,感觉显示很乱,分析的也不够全面... 试试其他的吧!今天电脑蓝屏了,就使用其dump文件测试,如下: 1.首先,最详细的,要属Osr Online这 ...
随机推荐
- GTID复制的搭建和问题处理
首先看一下什么是GTID: GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号. GTID实际上是由UUID+TID组成的.其中UUID是一个M ...
- 【SQL重温】面试之数据库基础练习
简介 最近在练习SQL基础,首先感叹一下,在机器上写和在纸上写还是有区别的. 本文的练习题目请点击此链接进行查看:http://www.cnblogs.com/edisonchou/p/3878135 ...
- CSV 文件读写
转自:http://www.cnblogs.com/Clin/archive/2013/03/14/2959022.html public class CSVFileHelper { /// < ...
- (转)浅谈PostgreSQL的索引
1. 索引的特性 1.1 加快条件的检索的特性 当表数据量越来越大时查询速度会下降,在表的条件字段上使用索引,快速定位到可能满足条件的记录,不需要遍历所有记录. create table t(id i ...
- AngularJs学习笔记--Understanding the Controller Component
原版地址:http://docs.angularjs.org/guide/dev_guide.mvc.understanding_model 在angular中,controller是一个javasc ...
- 阅读MySQL文档第20章:存储程序和函数
本文把阅读到的重点摘抄下来. 一.一个子程序要么是一个程序要么是一个函数.使用CALL语句来调用程序,程序只能用输出变量传回值.就像别其它函数调用一样,函数可以被从语句外调用(即通过引用函数名),函数 ...
- C++、Java、Objective-C、Swift 二进制兼容测试
鉴于目前动态库在iOS App中使用越来越广泛,二进制的兼容问题可能会成为一个令人头疼的问题.本文主要对比一下C++.Java.Objecive-C和Swift的二进制兼容问题. iOS端动态库使用情 ...
- Yii 不完全解决方案(一)
此文意在记录 Yii 开发过程中的小问题解决方案 1. Yii 中 Js 和 Css 文件的引入. 我们就从最简单的问题开始吧,说起来也不是问题,只是语法罢了.假设我们的 js 文件都放在和 prot ...
- 谈谈Ajax(二)
昨天还没有谈完,今天做一个了解. 首先还是以错误,来讲述. 一.AJax常见错误 Ajax常见的错误,除了昨天列举的之外.还有就是如下状态码: 405,请求类型错误,比如请求是POST,你却用GET, ...
- $Yeasion$的码风修改历程
总之,今天是一个值得纪念的伟大日子,我将自己的码风进行了彻底的修改,大概是参考了Pks和\(Rqy\)的码风,分为以下几点. 1.变量名.在所有的计算符号之前和之后加空格.如:"&& ...