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 $$

实战分析

  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 文件

core文件的分析

加载核心转储文件

gdb ./test.out ./core_test.ou_2024_1720274485

确定段错误源头

一旦gdb加载完毕,输入 bt 查看导致段错误的确切位置。这将显示导致崩溃的函数调用堆栈。

(gdb) bt
#0  __vfprintf_internal (s=0x0, format=0x55e2f70ec0c1 "%s,%s,%s,%g,%d,%.f,%ld,%ld\n", ap=ap@entry=0x7f1ec23ec8c0, mode_flags=mode_flags@entry=0) at ./stdio-common/vfprintf-internal.c:1218
#1  0x00007f1ec253a6ca in __fprintf (stream=<optimized out>, format=<optimized out>) at ./stdio-common/fprintf.c:32
#2  0x000055e2f70e0d48 in StoreMD::tick2csv (this=0x55e2f8836128, tick=..., timestamp=@0x7f1ec23ecac8: -62170013143, currentTime=@0x7f1ec23ecad0: 1720502827) at test.cpp:111

根据 gdb 的回溯信息,问题出现在 __vfprintf_internal 函数中,这是在格式化输出时发生的错误。具体到您的程序,问题可能是由于在 StoreMD::tick2csv 函数中使用了无效的字符串指针(s=0x0)导致的。

分析变量

使用 print 或 p 后跟变量名,检查程序中各个点的变量值。这有助于确定是否有任何变量为null或具有意外值。

比如我要查看并打印 StoreMD::tick2csv 函数中 key 变量的值。

  1. 设置断点:在 gdb 中设置断点,使程序在 StoreMD::tick2csv 函数内停下来。
(gdb) break test.cpp:111

这里假设 tick2csv 函数在 test.cpp 文件的第111行。您需要根据实际代码中该函数所在的位置进行调整。

  1. 运行程序:继续运行程序,直到达到设置的断点处。
(gdb) run
  1. 查看变量值:一旦程序停在断点处,您可以使用 print 命令查看 key 变量的值。
(gdb) print key

如果 key 是一个字符串或者字符数组,您可以使用 %s 格式化符号打印它的内容

(gdb) printf "%s\n", key

如果 key 是类 StoreMD 的成员变量,您需要访问该类实例的成员。假设 this 指针指向 StoreMD 类的实例,您可以这样做:

(gdb) print this->key

在 gdb 中,您可以使用 info locals 来查看当前函数的所有局部变量。

(gdb) info locals

  1. 继续执行:如果需要继续执行程序,使用 continue 命令:
(gdb) continue

检查内存访问

您可以使用 info registers 查看当前CPU寄存器的状态,这可能会提供有关崩溃原因的线索。

相关资料:

  • https://blog.csdn.net/ftswsfb/article/details/119192789
  • https://blog.51cto.com/u_13536788/9686757
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux segmentation fault core dumped是一个常见的错误提示,它通常意味着程序在运行时出现了严重的问题,导致操作系统无法继续执行进程并产生了core dump文件。core dump文件是系统在发生异常时自动生成的文件,它包含了发生异常时的内存状态,可以帮助开发者进行问题排查和调试。 Segmentation fault通常是由于程序访问了不属于它的内存区域所导致的。这可能是由于程序中的指针错误、数组越界访问、非法内存访问等原因引起的。当程序发生segmentation fault时,操作系统会将进程的状态保存到一个core dump文件中,以便后续进行调试和分析。 要查看core dump文件,可以使用以下命令: ```shell $ gdb <program_name> <core_dump_file> ``` 其中,`<program_name>`是发生segmentation fault的程序名称,`<core_dump_file>`是生成的core dump文件的路径。使用gdb工具可以打开core dump文件并进行调试,以找出导致segmentation fault的具体原因。 要解决segmentation fault问题,可以采取以下步骤: 1. 检查程序中的指针和内存访问是否正确,避免越界访问和非法内存访问。 2. 检查程序是否使用了动态分配的内存,并确保在使用完毕后释放了所有分配的内存。 3. 调试程序,使用gdb工具打开core dump文件并逐步执行程序,查看在发生segmentation fault时的内存状态,找出问题所在。 4. 如果问题仍然无法解决,可以尝试使用其他工具或方法进行调试和分析,例如使用valgrind等内存检测工具。 总之,Linux segmentation fault core dumped是一个常见的错误提示,它通常是由于程序访问了不属于它的内存区域所导致的。通过查看core dump文件并进行调试和分析,可以找出导致segmentation fault的具体原因并加以解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值