自学内容网 自学内容网

Segmentation fault (core dumped)

错误简介

出现 “Segmentation fault (core dumped)” 错误通常意味着程序访问了未分配的内存或者越界访问了已分配内存之外的区域。

段错误通常发生在以下情况:

  1. 空指针解引用:尝试对空指针进行操作。
  2. 内存越界:访问了超出分配内存边界的区域。
  3. 栈溢出:递归深度过大或者局部变量过多导致栈空间不足。

在遇到段错误时,常用的调试方法包括:

  • 使用调试器如 gdb 来跟踪程序运行时的状态,从而定位具体的错误发生位置。
  • 检查代码中的指针操作,确保不会解引用空指针或者越界访问。
  • 考虑使用内存检测工具(如 Valgrind)来帮助检测内存泄漏或者非法内存访问问题。

为什么 try-catch 捕获不到?

在 C++ 中,try-catch 语句主要用于捕获异常,而不是用来处理诸如段错误这样的底层内存访问问题。

core文件的生成

在ubuntu环境下,默认不生成core文件,需要生成core文件时,需要使用ulimit进行设定。
ulimit -c 判断是否开启转储,为0 则没有开启

1. 修改core文件路径

在Linux系统中,/proc/sys/kernel/core_pattern文件用于指定核心转储文件的命名模式。这个文件通常是一个特殊的虚拟文件,修改它会影响系统在发生程序崩溃或异常时生成的核心转储文件的命名方式。

默认内容如下

|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E

使用管理员模式,修改"/proc/sys/kernel/core_pattern"文件。

su
echo "core_%e_%p_%t" > /proc/sys/kernel/core_pattern

该路径为在执行文件当前路径创建相应的core文件,其中可选参数列表为:

%p - insert pid info filename
%u - insert current uid into filename
%g - insert current gid into filename
%s - insert signal that the coredump into the filename
%t - insert UNIX time that the coredump occurred into filename
%h - insert hostname where the coredump happened into filename
%e - insert coredumping executable name into filename

挑几个翻译下

- %e是执行文件名(可能被截断)
- %P是pid
- %t是coredump生成时间戳
- %s是触发生成coredump的信号值

注意:修改该文件后,如果重启Linux系统,该文件又会变回初始值。

2. 使能core文件生成

# 列出当前终端所有资源限制
ulimit -a 

# 设置生成core文件的大小:1024k
ulimit -c 1024

# 设置生成core文件的大小:不受限制
ulimit -c unlimited

注意:在终端通过ulimit命令设置core file size,仅在当前终端有效。
3. 验证core文件生成
在修改core文件路径和开启core文件生成后,可以使用kill命令简单验证core文件生成。

kill -s SIGSEGV $$

core文件的分析

分析核心文件(core dump file)通常是为了理解程序崩溃的原因或故障的根本问题。以下是分析核心文件的一般步骤:

  1. 确认调试工具安装
    确保系统上安装了用于分析核心文件的调试工具,例如gdb(GNU Debugger)或者适用于特定语言和环境的其他调试工具。

  2. 获取符号信息
    如果程序是用编译器的调试选项编译的(例如-g选项),则核心文件通常包含了符号信息,可以更好地分析。如果没有符号信息,分析将更具挑战性。

  3. 加载核心文件
    使用调试工具加载核心文件和程序执行文件(如果可用)。例如,在使用gdb时,可以执行:

    gdb /path/to/your/program /path/to/core/file
    
  4. 分析堆栈信息
    使用调试工具查看堆栈回溯(backtrace),这将显示程序在崩溃时的函数调用路径。在gdb中,可以使用bt命令:

    (gdb) bt
    
  5. 查看变量和内存状态
    如果有符号信息,可以查看在崩溃时程序的变量值和内存状态。这对于理解程序崩溃的原因非常有帮助。

  6. 分析核心转储的代码段和数据段
    核心文件通常包含程序崩溃时的代码段和数据段的快照。分析这些内容有助于理解程序在崩溃时的状态。

  7. 查找原因并调试
    根据堆栈信息和变量状态,尝试确定程序崩溃的确切原因。这可能涉及到查找空指针解引用、内存泄漏、未处理的异常等问题。

  8. 记录和报告
    如果能够找到程序崩溃的原因或者问题点,记录并报告给开发团队或相关人员,以便进行修复或进一步的调查。

实战分析

  1. 编译时用-g选项
g++ -g -o test.out test.cpp
  1. 修改core文件生成路径到当前执行文件同目录
echo "core_%e_%p_%t" > /proc/sys/kernel/core_pattern
  1. 设置生成core文件的大小:不受限制
ulimit -c unlimited

4.在当前终端运行程序,因为ulimit设置 只在当前终端有效。

./test.out

5.程序出错后会在执行同目录下生成类似 core_test.ou_2024_1720274485 文件,用gdb工具分析

gdb ./test.out ./core_test.ou_2024_1720274485

使用 gdb 检查变量:

你可以在 gdb 中使用 print 命令查看 queue 和 front 的值。例如:

(gdb) print queue
(gdb) print front

相关资料:

  • https://blog.csdn.net/ftswsfb/article/details/119192789
  • https://blog.51cto.com/u_13536788/9686757

原文地址:https://blog.csdn.net/weixin_57097753/article/details/140235831

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!