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这 ...
随机推荐
- Excel使用SUMIF函数注意事项
sumif函数的公式使用方法如下: =sumif(查询匹配的区域,条件,汇总求和的区域) 条件可以是“>10”或"=10"这种格式.其中“查询匹配区域”和“汇总求和区域”需要 ...
- lvm 相关
求教:/home分区和/root分区的关系 lvm扩容试验 [复制链接] lvm快速使用http://imysql.cn/2008_05_05_quick_startup_lvm Linux LVM学 ...
- Http协议和web本职【转自丁码农】
当你在浏览器地址栏敲入“http://www.cnblogs.com/”,然后猛按回车,呈现在你面前的,将是博客园的首页了(这真是废话,你会认为这是理所当然的).作为一个开发者,尤其是web开发人员, ...
- 使用简单的Java代码在SAP C4C里创建销售订单
需要创建的销售订单的明细通过硬编码指定: 比如销售订单的描述为Jerry Test 2019-1-23 16:05PM 执行之后,看到Status Code 201,说明创建成功: 到UI上能看到成功 ...
- sql2005 和 mysql 定时备份批处理
保存为sqlbak.bat 目录我直接放winrar 的根目录了 或者拷贝一个winrar.exe 具体目录随意. 然后添加计划任务个人的话建议一周或者一天 虚拟主机等 建议每周或者每月 @echo ...
- springmvc需要掌握的面试知识
1:讲下Spr ingMvc和Struts1,Struts2的比较的优势 性能上Struts1>SpringMvc>Struts2 开发速度上SpringMvc和Struts2差不多,比 ...
- 什么是Apache Isis
这个页面展示了一个现代的 Apache Isis 应用程序的外观. 下边是Isis 插件里的 todoapp 示例 (非 ASF)截图,你可以随意使用. 界面里对应的领域类可以在这里找到. 这个 to ...
- 用DecimalFormat格式化十进制数字的实际应用
在项目中,有时候我们需要将数字转换成特定的格式便于操作和使用.最常用的就是在操作价格数字的时候,需要将数字转换成小数点后保留两位小数,比如讲3.4转换成3.40 我们可以用DecimalFormat, ...
- HDU 2897 邂逅明下 ( bash 博弈变形
HDU 2897 邂逅明下 ( bash 博弈变形 题目大意 有三个数字n,p,q,表示一堆硬币一共有n枚,从这个硬币堆里取硬币,一次最少取p枚,最多q枚,如果剩下少于p枚就要一次取完.两人轮流取,直 ...
- 多python版本下,使用pip安装第三方库
说明:win10系统,先安装有Python3.5.2,后又安装了Python2.7.13(并重命名了Python27文件夹下python.exe为python2.7.13.exe),试图使用pip安装 ...