1.什么是coredump
一般的coredump文件为ELF格式,coredmp包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。许多程序和操作系统出错时会自动生成一个core文件。coredump可以用在很多场合,使用Linux系统在跑一些压力测试或者系统负载一大的话,系统就hang住了或者干脆system panic。这时唯一能帮助你分析和解决问题的就是coredump了。通常进程或者内核收到
通常情况下coredmp包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。可以理解为把程序工作的当前状态存储成一个文件。许多程序和操作系统出错时会自动生成一个core文件。signal 11(abort)
2.如何产生和控制Coredump
开启core dump可以使用命令ulimit开启,也可以在程序中通过setrlimit系统调用开启。
打开coredump功能,
1.在终端中输入ulimit -c ,输出结果为0,说明默认结果是关闭coredump的。
2.ulimit -c unlimited 开启coredump功能,并且不限制coredump文件的大小;如果要限制大小,将unlimited修改为数值即可。
3.上述方法只有对当前终端环境有效,想要永久生效,可以修改文件/etc/security/limits.conf.
# /etc/security/limits.conf
#
# each line describe a limit for a user in the form
#
# <domain> <type> <item> <value>
* soft core unlimited
4.修改coredump文件保存路径
默认生成的coredump文件保存在可执行文件啊所在目录下,文件名就叫core
通过修改/proc/sys/kernel/core_user_id,生成的core文件名将会变成core.pid.
echo 1> /proc/sys/kernel/core_user_pid
还可以通过修改/proc/sys/kernel/core_pattern,来控制生成core文件保存的位置及文件名格式。
echo "/tem/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern
//生成的coredump文件保存/tem/corefile目录下,文件格式为“core-文件名-pid-时间戳”
可以通过sysctl或者/proc中来设置core文件的文件名以及生成的路径等。
实际程序中可以通过cat /proc/pid/limits查看进程的资源限制,Max core file size中soft limit为coredump文件支持最大值,0则表示不会生成coredump文件
开启之后还可以设置coredump文件的格式化名字以及生成的路径,/proc/sys/kernel/core_uses_pid支持文件名中带有pid, /proc/sys/kernel/core_pattern可以设置格式化的core文件保存位置或文件名,例如如下示例说明echo "/corefile/core-%e-%p-%t" > core_pattern将会控制所产生的core文件会存放到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
3.读取coredump的命令
gdb exec_file core_file
使用GDB,先从可执行文件中读取符号表信息,然后读取Core文件。因为Core文件中没有符号表信息,需要加载相应的库文件,无法进行调试。
4.gdb调试
bt(backtrace)/info stack函数调用栈
info args 查看当前参数
info r(resgister)当前寄存器的值
info source 查看当前源程序
info frame 详细的当前栈层的信息
info threads 显示当前可调试的所有线程,前面有*的是当前调试的线程。
Thread + thread ID切换线程
f列出当前的函数
l(list)列出函数的实体
list num 列出当前文件的某行为中心的代码
l文件名或者文件名:行数 显示另外的源文件
连续的l(list) 接着上一次继续向下显示
l - 显示之前的代码
x(examine)检查内存值 x /NFU 地址
注:<N 显示个数,F显示格式(x,d,u,f),U显示的数据单位(b,h,w,g)>
p(print)打印变量的值
pt可以打印出变量的数据结构,而后p可以查看感兴趣的变量
layout:用于分割窗口,可以一边查看代码,一边测试:
layout src:显示源代码窗口
layout asm:显示反汇编窗口
layout regs:显示源代码/反汇编和CPU寄存器窗口
layout split:显示源代码和反汇编窗口
可以使用ctrl + x 然后ctrl +a进行窗口的切换。
Forward-search 字串 向前搜索源码
Reverse-search 字串 全部搜索
成功获取core文件,并将拷贝的core文件放入对应的process的程序工程目录下同一目录下且工程目录有process生成bin文件,cd到process的目录
XXX-XXX-XX-gdb bin core
进入gdb模式,调试中可能有一些库要用到,所以还要设置gdb中调用库的库文件的绝对路径,一般linux嵌入式一般是生成的文件系统作为调用路径
initially, you will see a lot of error messages. They can be ignored. Now on the gdb prompt, type:
(gdb) set solib-absolute-prefix SRCPATH/targets/PROFILE/fs.install
(gdb) bt
bt之后可以看见打印的堆栈信息。
造成程序coredump的原因
1 内存访问越界
2.多线程程序使用了线程不安全的函数。
3.多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump
4.非法指针
5.堆栈溢出
5.demo
gcc -g *.c -o *
./*
gdb ./* core_dump
时间紧就不传了,有需要的可以评论。
参考链接