ubuntu core 文件产生
关于内核转储的设置方法
1. 内核转储作用
(1) 内核转储的最大好处是能够保存问题发生时的状态。
(2) 只要有可执行文件和内核转储,就可以知道进程当时的状态。
(3) 只要获取内核转储,那么即使没有复现环境,也能调试。
2. 启用内核转储
1.1 查看内核转储是否有效
在终端中输入以下命令,查看内核转储是否有效。
#ulimit -c
0
-c 表示内核转储文件的大小限制,现在显示为零,表示不能用。
可以改为1G
#ulimit -c 1073741824
也可以改为无限制
#ulimit -c unlimited
2.2 测试一个例子
例子的源代码:
#include <stdio.h>
int main(void)
{
int *a = NULL;
*a = 0x1;
return 0;
}
把以上源代码,写成一个a.c文件后,编译a.c文件产生一个a.out的可执行文件:
#gcc -g a.c -o a.out
修改a.out文件的权限后,执行它:
#./a.out
就会显示:
Segmentation fault(core dump)
这表示在当前目录下, 已经生成了a.out对应的内核转储文件。
注意:后面带有(core dump), 才说明转储文件成功生成了。
#file core*
core:ELF 64-bit LSB core file x86-64, version 1(SYSV), SVR4-style, from './a.out'
coreDump: UTF-8 Unicode C program text
要用GDB调试内核转储文件,应该使用以下方式启动GDB:
#gdb -c ./*.core ./a.out
GNU gdb (GDB) 7.1-Ubuntu
...
Core was generated by './a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004004dc in main() at a.c:6
6 *a =0x1;
a.c的第6行收到了11号信号。用GDB的list命令可以查看附近的源代码。
(gdb) l 5
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int *a = NULL;
6 *a = 0x1;
7 return 0;
8 }
这里默认都是当前目录,也可以给core 和a.out 指定路径
到这里测试完成!
2.3 永久生效的办法
上面所述的方法,只是在当前shell中生效,重启之后,就不再有效了。永久生效的办法是:
#vi /etc/profile 然后,在profile中添加:
ulimit -c 1073741824
(但是,若将产生的转储文件大小大于该数字时,将不会产生转储文件)
或者
ulimit -c unlimited
这样重启机器后生效了。 或者, 使用source命令使之马上生效。
#source /etc/profile
3. 指定内核转储的文件名和目录
缺省情况下,内核在coredump时所产生的core文件放在与该程序相同的目录中,并且文件名固定为core。很显然,如果有多个程序产生core文件,或者同一个程序多次崩溃,就会重复覆盖同一个core文件。
我们可以通过修改kernel的参数,指定内核转储所生成的core文件的路径和文件名。
可以通过在/etc/sysctl.conf文件中,对sysctl变量kernel.core_pattern的设置。
#vi /etc/sysctl.conf 然后,在sysctl.conf文件中添加下面两句话:
kernel.core_pattern = /var/core/core_%e_%p
kernel.core_uses_pid = 0
保存后退出。
需要说明的是, /proc/sys/kernel/core_uses_pid。如果这个文件的内容被配置成1,即使core_pattern中没有设置%p,最后生成的core dump文件名仍会加上进程ID。
这里%e, %p分别表示:
%c 转储文件的大小上限
%e 所dump的文件名
%g 所dump的进程的实际组ID
%h 主机名
%p 所dump的进程PID
%s 导致本次coredump的信号
%t 转储时刻(由1970年1月1日起计的秒数)
%u 所dump进程的实际用户ID
可以使用以下命令,使修改结果马上生效。
#sysctl –p /etc/sysctl.conf
请在/var目录下先建立core文件夹,然后执行a.out程序,就会在/var/core/下产生以指定格式命名的内核转储文件。查看转储文件的情况:
#ls /var/core
core_a.out_2834
4. 手动强制某个进程产生core dump的方法(尝试)
当某些程序发生crash时,对应进程会产生coredump文件。通过这个coredump文件,开发人员可以找到bug的原因。但是coredump的产生,大都是因为程序crash了。
而有些bug是不会导致程序crash的,比如死锁,这时程序已经不正常了,可是却没有coredump产生。如果环境又不允许gdb调试,难道我们就束手无策了吗?
针对以上这种情况,一般情况下,对于这样的进程可以利用 watchdog监控它们,当发现这些进程很长时间没有更新其heartbeat时,可以给这些进程发送可以导致其产生coredump的信号。根据 linux的信号默认的处理行为,SIGQUIT,SIGABRT, SIGFPE和SIGSEGV都可以让该进程产生coredump文件。这样我们可以通过coredump来得知死锁是否发生。 当然, 如果进程添加了这些信号的处理函数,那么就不会产生coredump了。不过,对于SIGQUIT, SIGABRT, SIGFPE, SIGSEGV,有谁会为它们加上信号处理函数呢。
还有一种情况,进程并没有死锁或者block在某个位置, 但是我们需要在某个指定位置进行调试,获取某些变量或者其它信息。但是,有可能是客户环境或者生产环境,不允许我们进行长时间的检测。那么,我们就需要通 过coredump来获得进程在运行到该点时的快照。 这个时候,可以利用gdb来手工产生coredump。在attach上这个进程时,在指定位置打上断点,当断点触发时,使用gdb的命令gcore,可 以立即产生一个coredump。 这样,我们就拿到了这个位置的进程快照。
1.寻找您要发送信号的进程ID,
# ps -ef | grep qemu
root 3207 3206 44 10:32 pts/1 00:00:18 /usr/local/bin/qemu-system-x86
得出 qemu-system-x86的 PID号是3207
2.使用kill(1)去发送信号。
# /bin/kill -s QUIT 3207
发送其他的信号也很相似, 只要在命令行中替换QUIT 为ABRT,TERM 或 KILL 就行了
重要提示: 在系统上随意杀死进程是一个坏主意,特别是init(8),它的PID是1,它非常特殊。 可以运行 /bin/kill -s KILL 1 命令来让系统迅速关机。 当您按下 Return (回车)键之前,一定要 详细检查您运行 kill(1) 时所指定的参数。
5 使用core dump进行调试
在Linux下遇到“段错误”(segmentation fault),如果段错误发生在服务器端,而服务器端要继续工作,不允许调试,这时“内核转储(core dump)”就派上了用场,可以把生成的内核转储复制到本地进行调试。
首先,按照上面的永久生效方法,在服务器上进行相应设置。 然后程序在崩溃时,就会在程序所在目录(或自己指定的目录)生成一个core文件,把这个core文件拷到本地(最好与该进程对应的可执行文件放到同一个目录,若不然,在gdb时指出路径也可以)。
具体方法如下:
方法一:
输入命令 #gdb <程序可执行文件> <coredump转储文件>
例如:
# gdb /usr/local/bin/qemu-system-x86_64 /var/core/core-3207-qemu-system-x86
然后,在(gdb)提示符后输入 l, 会显示main主函数
方法二:
(1) 在终端输入命令# gdb [-c] <coredump文件>,
例如: gdb -c /var/core/core-3207-qemu-system-x86
(2)然后,在(gdb)提示符后输入file <可执行程序>
例如:(gdb) file /usr/local/bin/qemu-system-x86_64
(3) 这时就可以用backtrace/thread等命令查看当时的错误了,就像程序在本地执行到崩溃点一样
或者用where回车, 也可以显示程序在哪一行当掉的
5. 启用整个系统的内核转储
(未完待续......)
(4.1) 编辑/etc/profile, 开启登录到系统的所有用户的内核转储功能
首先,看看用的是个什么机器:
# uname –a
Linux ubuntu240 2.6.32-21-server #32-Ubuntu SMP Fri Apr 16 09:17:34 UTC 2010 x86_64 GNU/Linux
其次,再查看一些默认参数,若core file size是0,即使程序出错时,也不会产生core文件。
# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
查看栈信息
当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入“栈”(Stack)中。你可以用GDB命令来查看当前的栈中的信息。
下面是一些查看函数调用栈信息的GDB命令:
backtrace
bt
打印当前的函数调用栈的所有信息。如:
(gdb) bt
#0 func (n=250) at tst.c:6
#1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30
#2 0x400409ed in __libc_start_main () from /lib/libc.so.6
从上可以看出函数的调用栈信息:__libc_start_main --> main() --> func()
backtrace
bt
n是一个正整数,表示只打印栈顶上n层的栈信息。
backtrace <-n>
bt <-n>
-n表一个负整数,表示只打印栈底下n层的栈信息。
如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。
frame
f
n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
up
表示向栈的上面移动n层,可以不打n,表示向上移动一层。
down
表示向栈的下面移动n层,可以不打n,表示向下移动一层。
上面的命令,都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三个命令:
select-frame 对应于 frame 命令。
up-silently 对应于 up 命令。
down-silently 对应于 down 命令。
查看当前栈层的信息,你可以用以下GDB命令:
frame 或 f
会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。
info frame
info f
这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如:
(gdb) info f
Stack level 0, frame at 0xbffff5d4:
eip = 0x804845d in func (tst.c:6); saved eip 0x8048524
called by frame at 0xbffff60c
source language c.
Arglist at 0xbffff5d4, args: n=250
Locals at 0xbffff5d4, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffff5d4, eip at 0xbffff5d8
info args
打印出当前函数的参数名及其值。
info locals
打印出当前函数中所有局部变量及其值。
info catch
打印出当前的函数中的异常处理信息。
http://my.oschina.net/u/219482/blog/313598
ubuntu core 文件产生相关推荐
- Gdb 调试core文件详解
一,什么是coredump 我们经常听到大家说到程序core掉了,需要定位解决,这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止,并且在满足一定条件下(这里为什么说需要 ...
- linux adb arm移植,移植ubuntu core到Arm开发板
origin: http://blog.csdn.net/kickxxx/article/details/15341079 最初是想把整个ubuntu移植到MX51开发板,因为项目不需要运行桌面系统, ...
- gdb 笔记(02)— gdb 调试执行(启动调试、添加参数、附加到进程、调试 core 文件)
在编译程序时,使用 gcc 或者 g++ 时一定要加上 -g 选项,如 gcc -g -o hello hello.c 以便调试程序含有调试符号信息,从而能够正常调试程序.否则则会出现如下提示,导致不 ...
- 到底snappy ubuntu core是什么?
我不知到大家有没有听过snappy ubuntu core.反正我第一次听到Snappy时,不是很理解.如果我们查查字典,它的意思是爽快的,敏捷的,精力充沛的.听起来非常不错哦!对了Snappy就是C ...
- 微软azure云在Ubuntu Core中的应用
在今天的教程中,我们来展示如何在Ubuntu Core中使用azure的IoT hub来开发我们的应用.Azure IoT Hub目前提供了一个框架对我们的IoT设备进行管理,并可以通过预置解决方案来 ...
- Ubuntu Core 18 发布:提供 10 年安全更新;美劳工部指控甲骨文薪酬歧视
(给技术最前线加星标,每天看技术热点) 转自:开源中国.solidot.cnBeta.腾讯科技.快科技等 [技术资讯] 0.嵌入式系统 Ubuntu Core 18 发布:提供 10 年安全更新 Ca ...
- linux生成core文件路径,core文件生成和路径设置
在程序崩溃时,内核会生成一个core文件,即程序最后崩溃时的内存映像,和程序调试信息. 之后可以通过gdb,打开core文件察看程序崩溃时的堆栈信息,可以找出程序出错的代码所在文件和函数. 1.cor ...
- linux dump core 文件位置,Linux core dump使用
什么是 core dump? core dump是一个当进程意外终止时包含进程内存内容的文件.当程序崩溃的时候,core dump由kernel触发.core dump能够做为程序崩溃时的过后快照(p ...
- GDB调试core文件详解
一,什么是coredump 我们经常听到大家说到程序core掉了,需要定位解决,这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止,并且在满足一定条件下(这里为什么说需要 ...
最新文章
- Linux学习之获取帮助
- 弹出无toobar的网页
- Python 可轻松获取天气数据、可视化分析
- JAVA实现网页版斗地主_Java实现斗地主案例
- 转录组测序(质控、比对、计数)
- C#姓名与机构名称生成专用类
- MATLAB安装 C盘空间不足问题解决
- 生产计划管理APS系统在食品调味品/复合调味品行业的应用(2)--APS系统功能介绍
- MyBatis-Plus--自动填充的用法
- conv1d(): argument ‘padding‘ (position 5) must be tuple of ints, not str 这个错误是怎么回事呀?请各位帮忙看看,万分感谢
- 安卓毕业设计- 基于Android的旅游计划APP
- 为什么mysql打开闪屏_MAC下的一些快捷键和实用软件
- 机器学习总结之——各种距离汇总
- 2014年湛江新教育交流会总结
- IDEA 插件的设置和引用,以及插件库
- 王春亮阿育吠陀推拿心学
- 软件开发应届生求职经验(其他专业可参考)
- 操作系统-第四章存储器管理 计算题:已知逻辑地址求物理地址
- 基于小米8和LineageOS的Android系统开发
- 为什么从机械转专业到计算机