Linux上调试core文件(Good)
coredump文件
什么是coredump?
通常情况下coredmp包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。可以理解为把程序工作的当前状态存储成一个文件。许多程序和操作系统出错时会自动生成一个core文件。
造成程序coredump的原因很多,这里根据以往的经验总结一下:
1 内存访问越界
a) 由于使用错误的下标,导致数组访问越界
b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符
c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。
2 多线程程序使用了线程不安全的函数。
应该使用下面这些可重入的函数,尤其注意红色标示出来的函数,它们很容易被用错:
asctime_r(3c) gethostbyname_r(3n)
getservbyname_r(3n) ctermid_r(3s) gethostent_r(3n)
getservbyport_r(3n) ctime_r(3c)
getlogin_r(3c) getservent_r(3n) fgetgrent_r(3c) getnetbyaddr_r(3n)
getspent_r(3c) fgetpwent_r(3c) getnetbyname_r(3n) getspnam_r(3c)
fgetspent_r(3c) getnetent_r(3n) gmtime_r(3c)
gamma_r(3m) getnetgrent_r(3n) lgamma_r(3m) getauclassent_r(3)
getprotobyname_r(3n) localtime_r(3c)
getauclassnam_r(3) etprotobynumber_r(3n) nis_sperror_r(3n) getauevent_r(3)
getprotoent_r(3n) rand_r(3c)
getauevnam_r(3) getpwent_r(3c) readdir_r(3c)
getauevnum_r(3) getpwnam_r(3c)strtok_r(3c)
getgrent_r(3c) getpwuid_r(3c) tmpnam_r(3s) getgrgid_r(3c) getrpcbyname_r(3n)
ttyname_r(3c) getgrnam_r(3c) getrpcbynumber_r(3n) gethostbyaddr_r(3n)
getrpcent_r(3n)
3 多线程读写的数据未加锁保护。
对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump
4 非法指针
a) 使用空指针
b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型
的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它
时就很容易因为bus error而core dump. 总线错误(bus error)通常是指针强制转换,导致CPU读取数据违反了一定的总线规则。《c专家编程》
#include <stdlib.h> #include <stdio.h> #if defined(__GNUC__) # if defined(__i386__) /* Enable Alignment Checking on x86 */ __asm__("pushf\norl $0x40000,(%esp)\npopf"); # elif defined(__x86_64__) /* Enable Alignment Checking on x86_64 */ __asm__("pushf\norl $0x40000,(%rsp)\npopf"); # endif #endif int main() { union{ char a[10]; int i; }u; int *p =(int*)&(u.a[1]); *p =17; printf("%d\n", *p); } |
原因是:
x86体系结构会把地址对齐之后,访问两次,然后把第一次的尾巴和第二次的头拼起来。
如果不是x86,那种体系结构下的机器不肯自动干这活,就会产生core。
如果在代码中将对齐检查功能打开,运行后能显示bus error。
5 堆栈溢出
不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
1.core文件的生成开关和大小限制
---------------------------------
1)使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。
2)使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。
#ulimit -c 300
若ulimit -c unlimited,则表示core文件的大小不受限制。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件。在调试此
core文件的时候,gdb会提示错误。
2.core文件的名称和生成路径
----------------------------
一、设置core文件相关参数
临时修改
若系统生成的core文件不带其它任何扩展名称,则全部命名为core。新的core文件生成将覆盖原来的core文件。
1)/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。文件内容为1,表示添加pid作为扩展名,生成的core文件格式为core.xxxx;为0则表示生成的core文件同一命名为core。
可通过以下命令修改此文件:
echo "1" > /proc/sys/kernel/core_uses_pid
2)proc/sys/kernel/core_pattern可以控制core文件保存位置和文件名格式。可通过以下命令修改此文件:
echo "/corefile/core-%e-%p-%t" > core_pattern,可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
永久修改:
方法一:使用sysctl -w name=value命令。 例:/sbin/sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t
方法二:
设置core dump文件位置
vi /etc/sysctl.conf
修改(添加)如下两个变量
kernel.core_pattern =/var/core/core_%e_%p
kernel.core_uses_pid= 0
这里是改为生成目录在/var/core/,%e代表程序名称,%p是进程ID
如果想直接生成在可执行文件相同目录,前面不要加任何目录,直接
kernel.core_pattern =core_%e_%p
步骤三:让修改生效
sysctl -p/etc/sysctl.conf
如果想直接生成在可执行文件相同目录,前面不要加任何目录(远程没效果,存疑)
以下是参数列表:
%p - insert pid into filename 添加pid
%u - insert current uid into filename 添加当前uid
%g - insert current gid into filename 添加当前gid
%s - insert signal that caused the coredump into the filename
添加导致产生core的信号
%t - insert UNIX time that the coredump occurred into filename
添加core文件生成时的unix时间
%h - insert hostname where the coredump happened into filename
添加主机名
%e - insert coredumping executable name into filename
添加命令名
二、.用gdb查看core文件:
发生coredump之后,用gdb进行查看core文件的内容,以定位文件中引发coredump的行.
gdb [execfile] [core file]
如: #gdb ./test core.22773
在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump发生在哪一行?
Linux上调试core文件(Good)的更多相关文章
- [转载] Linux 下产生和调试core文件
原地址:http://blog.csdn.net/shaovey/article/details/2744487 linux下如何产生core,调试core 在程序不寻常退出时,内核会在当前工作目录下 ...
- Linux下交叉编译gdb,gdbserver+gdb的使用以及通过gdb调试core文件
交叉编译gdb和gdbserver 1.下载gdb:下载地址为:http://ftp.gnu.org/gnu/gdb/按照一般的想法,最新版本越好,因此下载7.2这个版本.当然,凡事无绝对.我们以gd ...
- Visual Studio 2017 通过SSH 调试Linux 上.NET Core
Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Studio 2017 部署环境:Ubuntu ...
- VS2017 Linux 上.NET Core调试
调试Linux 上.NET Core Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Stud ...
- GDB调试core文件(3)
列出一些常见问题: 一,如何使用core文件 使用core文件 在core文件所在目录下键入: gdb -c core 它会启动GNU的调试器,来调试core文件,并且会显示生成此core文件的程序名 ...
- 如何设置、查看以及调试core文件
http://blog.csdn.net/xiaoxiaoniaoer1/article/details/7740820 1.core文件的生成开关和大小限制--------------------- ...
- 发布项目到 Linux 上运行 Core 项目
发布项目到 Linux 上运行 Core 项目 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 ASP.Net Core 给我们带来的最大的亮点就是跨平台,我在我电脑(win ...
- gd调试命令,gdb调试core文件
使用 gcc -g test.c -o test.out 编译程序,只有加-g参数才支持gdb调试: 然后 gdb ./test.out 运行可执行文件,进入gdb调试模式(gdb),在括号后面的输入 ...
- 解决gdb 调试 core 文件函数名显示为问号的问题
关于gdb调试core文件总是一堆问号的问题 问题描写叙述:已经在编译选项中增加了-g,可是查看core文件时.还是一堆问号,使用的命令为:gdb -c core 解决方式:因为gdb -c core ...
随机推荐
- 技本功丨用短平快的方式告诉你:Flink-SQL的扩展实现
2019年1月28日,阿里云宣布开源“计算王牌”实时计算平台Blink回馈给ApacheFlink社区.官方称,计算延迟已经降到毫秒级,也就是你在浏览网页的时候,眨了一下眼睛,淘宝.天猫处理的信息已经 ...
- Weighted Median
For n elements x1, x2, ..., xn with positive integer weights w1, w2, ..., wn. The weighted median is ...
- lintcode-473-单词的添加与查找
473-单词的添加与查找 设计一个包含下面两个操作的数据结构:addWord(word), search(word) addWord(word)会在数据结构中添加一个单词.而search(word)则 ...
- C++ Primer Plus学习:第五章
C++入门第五章:循环和关系表达式 for循环 for循环的组成部分 设置初始值. 执行测试,看循环是否应该继续执行. 执行循环操作. 更新用于测试的值. 以上操作由括号括起,每个部分均是一个表达式, ...
- Java JVM多线程
- [Prism框架实用分享]如何在Prism应用程序中使用日志
前言 在Prism中有关日志的命名空间: Microsoft.Practices.Prism.Logging 在Prism中,你可以使用Prism自带的Logger(比如TextLogger等),也可 ...
- 0325 实验一操作系统模拟cmd
实验一.命令解释程序的编写 专业:商软(2)班 姓名:韩麒麟 学号:201406114253 一. 实验目的 (1)掌握命令解释程序的原理: (2)掌握简单的DOS调用方法: (3)掌握C语言编程 ...
- 结对编程学习fault、error、failure三种状态
点滴成就 学习时间 新编写代码行数 博客量(篇) 学习知识点 第一周 10小时 0 0 了解软件工程 第二周 10小时 0 1 项目开题 第三周 15小时 0 1 开通博客.开展项目调查 第四周 20 ...
- SpringMVC 应知应会
springMVC 是表现层技术,可以用来代替 struts2,下面是简略图:主要是处理器和视图,只有这两个部分需要编写代码. springMVC 三大组件:处理器映射器,处理器适配器,视图解析器. ...
- 第198天:js---内置对象的原型链和其他知识
一.内置对象的原型链 1.Object原型 function test() {} alert(test.toString()); //新增属性 Object.prototype.mytest = fu ...