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这 ...
随机推荐
- SQL点点滴滴_聚集索引设计指南-转载
聚集索引基于数据行的键值在表内排序和存储这些数据行, 每个表只能有一个聚集索引, 因为数据行本身只能按一个顺序存储. 有关聚集索引体系结构的详细信息, 请参阅 聚集索引结构. 每个表几乎都对列定义聚集 ...
- SVNKit学习——Setting Up A Subversion Repository 创建仓库(三)
所谓Setting Up A Subversion Repository,就是在Subversion所在的服务器上创建一个仓库,说白了就是在磁盘上建一个特殊的目录,这里我以windows举例. 1.使 ...
- Rabbit MQ config文件解析
Rabbit MQ config文件解析 tcp_listeners:用于监听AMQP连接的端口或主机名/对(不带TLS),默认端口:5672 2.numtcpacceptors :将接受TCP侦听器 ...
- Angular4 微信的坑
1.不要重置对象的引用!(重置只应该在组件或服务的初始化时) why:会使页面产生闪烁 2.不要给图片绑定一个空的值或空的图片引用(如果值从服务器异步过来,那应该在初始化时给它一个默认值) why:会 ...
- Python学习---重点模块之xml
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单 数据准备 <?xml version="1.0"?> <data&g ...
- ignore_user_abort函数制定计划任务
PHP中的ignore_user_abort函数是当用户关掉终端后脚本不停止仍然在执行,可以用它来实现计划任务与持续进程,下面会通过实例讨论ignore_user_abort()函数的作用与用法. ...
- IDEA 搭建Java WEB 开发环境
本文是一篇讲解如何在 目前比较流行的IntellJ IDEA 下搭建JavaWEB的说明文档, 如有写的不详细的地方,希望各位留下自己宝贵的意义. Tips : 遇到的问题 , 请耐心看完文章,在文章 ...
- 百度地图label样式修正
现象:百度地图 label 宽度为0,文字在标签边框外. 原因:样式冲突,在css中添加下列代码即可: .BMapLabel{ max-width:none; }
- 支持向量机通俗导论(理解SVM的三层境界)[转]
作者:July .致谢:pluskid.白石.JerryLead.说明:本文最初写于2012年6月,而后不断反反复复修改&优化,修改次数达上百次,最后修改于2016年11月.声明:本文于201 ...
- 装饰模式案列(OutputStream)
使用装饰模式进行装饰OutputStream 写入文件成功 装饰类继承OutputStream类 DecorOutputStream package com.wbg.springRedis.decor ...