在Linux系统中,当应用程序遇到不可恢复的错误时,如段错误(Segmentation fault),系统会生成一个核心转储文件(core dump)。这个文件包含了进程崩溃时刻的内存映像、寄存器状态以及堆栈信息,是分析和调试程序崩溃原因的重要工具。本文将深入探讨如何利用core dump进行Linux应用程序的调试,特别关注使用gdb工具来解析core文件。 ### coredump的核心概念 #### 1. 何时产生core dump? 当进程接收到某些信号(如SIGSEGV)时,如果内核被配置为允许生成core dump,那么它就会创建一个包含进程内存映像的文件。除了SIGSEGV外,其他信号也可能触发core dump的生成,例如: - SIGABRT:通常由abort()函数发出。 - SIGBUS:访问不存在或未对齐的内存地址时发出。 - SIGFPE:执行数学运算错误时发出。 - SIGILL:执行非法指令时发出。 - SIGQUIT:用户通过键盘或其他方式请求退出时发出。 - SIGSYS:无效系统调用时发出。 - SIGTRAP:硬件陷阱或软件断点时发出。 #### 2. 如何控制core dump的大小? 默认情况下,为了保护系统资源,Linux系统可能限制core dump的大小。这可以通过`ulimit -c`命令查看。若要改变限制,可以使用`ulimit -c unlimited`,但这通常需要root权限。此外,也可以通过修改`/proc/sys/kernel/core_pattern`文件来控制core dump的存储位置和格式。 ### 使用gdb进行core dump分析 #### 1. 加载core dump 一旦有了core dump文件,就可以使用gdb加载它来分析崩溃的原因。确保gdb已安装,然后运行以下命令: ```bash gdb /path/to/executable_file /path/to/core_file ``` 例如: ```bash gdb ./test core.2890 ``` #### 2. 分析core dump 加载core dump后,gdb会显示程序崩溃时的调用堆栈。你可以使用`bt`(backtrace)命令查看调用堆栈,使用`info registers`查看寄存器状态,使用`list`查看源代码,使用`print`命令打印变量值等。这些信息对于定位问题至关重要。 #### 3. 示例分析 假设我们有如下的程序结构: - mylib.h:包含一个add函数的声明。 - mylib.c:实现add函数,在其中故意触发段错误。 - main.c:调用add函数,并打印结果。 - Makefile:用于编译上述文件。 编译并运行该程序时,由于add函数中存在非法内存访问(`*pc=10;`),程序会在运行时抛出Segmentation fault。此时,系统会生成一个core dump文件。使用gdb加载这个core dump,我们可以看到程序崩溃发生在add函数内部,即非法内存访问的地方。 ### 结论 core dump是Linux系统提供的一种强大的调试工具,能够帮助开发者深入了解程序崩溃的具体原因。通过合理配置core dump的生成条件和使用gdb工具进行分析,可以极大地提高问题定位的效率。然而,值得注意的是,core dump的生成和分析往往涉及到较为复杂的系统配置和编程知识,对于初学者来说可能有一定的学习曲线。
<leohe.leohe@gmail.com>
Linux系统中在应用程序运行过程中经常会遇到程序突然崩溃,提示:Segmentation fault,这是因为应用程序收到了SIGSEGV信号。这个信号提示当进程发生了无效的存储访问,当接收到这个信号时,缺省动作是:终止w/core。 终止w/core的含义是:在进程当前目录生成core文件,并将进程的内存映象复制到core文件中,core文件的默认名称就是“core”(这是Unix类系统的一个由来已久的功能)。
事实上,并不是只有SIGSEGV信号产生coredump,还有下面一些信号也产生coredump:SIGABRT(异常终止)、SIGBUS(硬件故障)、SIGEMT(硬件故障)、SIGFPE(算术异常)、SIGILL(非法硬件指令)、SIGIOT(硬件故障),SIGQUIT,SIGSYS(无效系统调用),SIGTRAP(硬件故障)等。
在程序的开发调试阶段(尤其是大型软件开发),发生程序异常崩溃时常规的调试方法常常是无比的痛苦:无穷的log中也不见得有什么有意义的信息。好在GDB提供和利用core文件进行调试的途径,大大方便了这类问题的调试。
下面我们通过一个简单的例子来看看怎么通过GDB来调试一个违规访问内存导致的程序崩溃。这里我们顺便讲讲动态库的调试。
/******** mylib.h **********/
#ifndef __MY_LIB_H__
#define __MY_LIB_H__
int add(int x, int y);
#endif // __MY_LIB_H__
/******** end **********/
/******** mylib.c **********/
#include <stdlib.h>
#include "mylib.h"
int add(int x, int y)
{
char* pc = NULL;
*pc = 10;
}
/******** end **********/
/******** main.c **********/
#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
int main (void)
{
int ret = -1;
int a = 10, b = 20;
ret = add(a, b);
printf("The result is: %d\n", ret);
return 0;
}
/******** end **********/
#####################################
# File Name: Makefile
#
#####################################
CC = gcc
LD = gcc
剩余5页未读,继续阅读
- potato_hi22012-04-20内容很少, 大概介绍了一下,没细节
- 粉丝: 4
- 资源: 5
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- asm-西电微机原理实验
- Arduino-arduino
- C语言-leetcode题解之70-climbing-stairs.c
- C语言-leetcode题解之68-text-justification.c
- C语言-leetcode题解之66-plus-one.c
- C语言-leetcode题解之64-minimum-path-sum.c
- C语言-leetcode题解之63-unique-paths-ii.c
- C语言-leetcode题解之62-unique-paths.c
- C语言-leetcode题解之61-rotate-list.c
- C语言-leetcode题解之59-spiral-matrix-ii.c