linux系统下产生Segmentation fault 与 Segmentation fault (core dumped)!!!

最近在学习的过程中,遇到了Segment fault(段错误)的问题,经过一番查找资料,学到了一些相关知识,这里做一个梳理,以防以后在遇到类似的问题,并且希望能够帮助到大家一丝丝!

什么是Segment fault

在操作系统中,内存被划分为多个段(Segments),每个段存储着不同类型的数据,如代码段、数据段等。Segmentation Fault(段错误)是一种常见的程序错误,它通常发生在程序试图访问无效的内存地址或未初始化的内存区域,或者指针操作不当、数组越界、动态内存分配问题等原因造成的。这种错误通常由于程序编写错误或指针使用不当导致。当程序执行过程中发生Segmentation Fault错误时,操作系统会向程序发送一个SIGSEGV信号,导致程序停止运行。

Segmentation Fault的常见原因

  • 指针操作不当:当指针未初始化、指向无效地址或已释放的内存时,程序会尝试访问这些地址,导致Segmentation Fault错误,非法指针:使用空指针,或者随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump。。
  • 数组越界:程序在访问数组时,如果索引超出数组的实际范围,将会访问到无效的内存区域,从而引发Segmentation Fault
  • 动态内存分配问题:在使用动态内存分配函数(如malloc、new等)时,如果分配的内存未初始化或已释放,程序仍然尝试访问这些内存,同样会导致Segmentation Fault
  • 堆栈溢出.不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。

如何解决Segmentation Fault错误。

实际上,我们可以通过仔细检查代码去逐一排查错误发生点,但是面对一个庞大的项目,涉及到的内容很多的时候,我们一一排查就会很吃力,有时候也是徒劳的。这时,我们就可以借助一些调试工具,来检查错误的位置。

下面来讲一下,在Linux系统中,如何借助gdb查看core文件来定位错误!

什么是core文件?

在Linux系统下,当程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息,编译时需要加上 -g -Wall)。我们使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。

如何生成core文件和大小限制

当系统程序运行产生 Segmentation Fault 而不是显示Segmentation fault (core dumped) 这说明,并没有产生code文件,我们需要执行以下命令来生成code文件,并限制文件大小。

  • 使用ulimit -c命令查看core文件的生成开关,如果结果为 0,则表示关闭了此功能,不会生成core文件。
  • 使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。
  • 但是如果生成的信息超过我们限制的文件大小,信息将会被裁剪,最终生成一个不完整的core文件或者根本就不生成,同时在调试此core文件的时候,gdb也会提示错误。所以我们常使用ulimit -c unlimited来表示core文件的大小不受限制。
  • 执行ulimit -a 察看当前系统设置
    在这里插入图片描述

注意:,这只对一个终端有效,再打开一个终端就无效了,要想整体修改,我们需要在系统 /etc/profile文件的最后,添加以下一行:

ulimit -c unlimited

然后,执行以下命令,使其生效:

source /etc/profile

这时候我们再次运行程序,就会发现Segmentation fault (core dumped),说明已经生成了code文件,但是它在哪呢?

查询core dump文件路径,可以通过以下命令查询:

cat /proc/sys/kernel/core_pattern

或者

/sbin/sysctl kernel.core_pattern

在这里插入图片描述
core文件的名称: core文件生成路径:输入可执行文件运行命令的同一路径下。若系统生成的core文件不带其它任何扩展名称,则全部命名为core。新的core文件生成将覆盖原来的core文件。

/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。

文件内容为1,表示添加pid作为扩展名,生成的core文件格式为core.xxxx;为0则表示生成的core文件同一命名为core。
可通过以下命令修改此文件:

echo "1" > /proc/sys/kernel/core_uses_pid 

修改core文件保存位置和文件名格:

修改/proc/sys/kernel/core_pattern, 可通过以下命令修改此文件:

echo "/corefile/core-%e-%p-%t" > core_pattern

可以将core文件统一生成到/corefile目录(必须保证有这个目录)下,也可以自己指定生成路径,产生的文件名为core-命令名-pid-时间戳,以下是参数列表:
%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 添加命令名

注意:

  • 目录proc文件系统是一个伪文件系统,以文件系统的方式为访问系统内核数据的操作提供接口。/proc目录的内容为系统启动时自动生成的,某写文件可改,某写文件不可改。比如可以通过修改proc的文件微调内核参数。使用vi可能无法成功编辑proc/sys/kernel/core_pattern,只能使用echo命令修改或者命令sysctl修改。sysctl命令如下:
sysctl -w "kernel.core_pattern=$core_dir/core_%e_%t" >/dev/null  
sysctl -w "kernel.core_uses_pid=0" >/dev/null

此时,我们就产生了code文件

在这里插入图片描述

如何利用code文件进行调试呢

  • 安装gdb
yum install -y gdb.x86_64
  • gdb进行查看core文件的内容, 以定位文件中引发core dump的行,gdb格式如下:
    gdb [exec file] [core file]
    [exec file]表示之前使用gcc编译的程序
    [core file]表示之前产生的dump文件
  • 基本GDB命令
    启动程序:run
    设置断点:b 行号|函数名
    删除断点:delete 断点编号
    禁用断点:disable 断点编号
    启用断点:enable 断点编号
    单步跟踪:next (简写 n)
    单步跟踪:step (简写 s)
    打印变量:print 变量名字 (简写p)
    设置变量:set var=value
    查看变量类型:ptype var
    顺序执行到结束:cont
    顺序执行到某一行: util lineno
    打印堆栈信息:bt
  • 切记:要在编译时,加上-g选项

举个栗子吧~

在这里插入图片描述
这里我们看到我们的code文件,接下来,使用以下命令,进行调试:
在这里插入图片描述
产生了以下结果:在这里插入图片描述
这里就会知道我们出现错误的位置。

新的问题又来了,我们从上图可以看出,缺少缺失独立的调试信息,该怎么办呢?

何为“独立的调试信息”?如果编写代码后使用gcc编译器进行编译时,若不加上-g编译参数,或后期使用strip工具进行二次处理,生成的二进制文件中将不带调试段信息,而gdb的调试都是基于该调试段进行的,在linux世界这部分内容往往也被称作debuginfo。
其次,各大发行版提供的二进制软件包为了缩小体积,且用户往往不需要对软件(包括内核、libc这类基础设施)本身进行调试,因此往往不带调试信息。由于在Linux环境下绝大部分程序都依赖于libc(包括最简单的hello world),若系统预装的libc未带调试段信息,将影响gdb对目标程序进行调试操作。

该如何解决呢?
  • 首先,执行以下命令
vim /etc/yum.repos.d/CentOS-Debuginfo.repo

将enable改为1
在这里插入图片描述

  • 安装glibc
yum install glibc
yum install yum-utils
debuginfo-install glibc-2.17-326.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64 

实际上,最后一句命令就是图片中提示的。
在这里插入图片描述

再次使用gdb,就发现不会提示Missing separate debuginfos, u.....啦~
在这里插入图片描述

通过where,我们可以看一些具体的细节:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/598431.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为AI全栈生态布局:中国科技巨头加速创新

华为AI芯片生态全栈深度分析 2024 一、引言 1.1 华为AI芯片发展背景: 华为,通信和消费电子巨头,以其技术创新和远见著称。2013年,华为率先布局人工智能(AI),并专注于全栈AI解决方案的开发。华…

骨传导耳机哪个品牌值得入手?精选五款高性能骨传导耳机,闭眼入都不踩雷!

随着健康生活的日益普及,运动健身逐渐成为人们生活中的重要组成部分。在这一背景下,骨传导耳机作为一种新型蓝牙耳机,凭借其不堵塞耳道、防水性能强等特性,受到了广大运动爱好者的喜爱。然而,骨传导耳机的热销也吸引了…

一次性邮箱API发送邮件的方法?如何配置?

一次性邮箱API发送邮件有哪些注意事项?怎么安全发信? 随着网络安全问题的日益凸显,如何安全、高效地发送邮件成为了一个亟待解决的问题。一次性邮箱API的出现,为我们提供了一种新的解决方案。那么,如何使用一次性邮箱…

白酒:白酒香型的国际化推广与市场接受度分析

云仓酒庄的豪迈白酒一直有在白酒香型的国际化推广。随着中国白酒市场的不断扩大和国际化的趋势,了解白酒香型的国际接受度和推广策略对于酒厂和整个行业都具有重要意义。 首先,国际化推广需要深入了解国际市场的需求和消费者偏好。不同国家和地区的消费者…

长难句打卡5.7

In December 2010 America’s Federal Trade Commission (FTC) proposed adding a “do not track” (DNT) option to Internet browsers, so that users could tell advertisers that they did not want to be followed. 2010年12月,美国美国联邦贸易委员会(FTC)提…

020、Python+fastapi,第一个Python项目走向第20步:ubuntu 24.04 docker 安装mysql8集群+redis集群(一)

系列文章 pythonvue3fastapiai 学习_浪淘沙jkp的博客-CSDN博客https://blog.csdn.net/jiangkp/category_12623996.html 前言 docker安装起来比较方便,不影响系统整体,和前面虚拟环境有异曲同工之妙,今天把老笔记本T400拿出来装了个ubuntu24…

Spring AOP(3)

目录 Spring AOP原理 代理模式 代理模式中的主要角色 静态代理 动态代理 总结:面试题 什么是AOP? Spring AOP实现的方式有哪些? Spring AOP实现原理 Spring使用的是哪种代理方式? JDK和CGLIB动态代理的区别? Spring AOP原理 代理模式 代理模式, 也叫委托模式. …

CUDA C编程:第一个程序 向量相加

我的电脑没有装CUDA,所以使用租了带GPU的云服务器,然后使用vscode SSH远程连接云服务器。云GPU使用的是智星云,0.8元/h。 智星云 可以使用nvcc --version查看系统中安装的CUDA版本。 然后写第一个CUDA程序,两个向量相加结果给到…

绝地求生:季后赛名额确定!NH战队总积分榜排名第一!

2024年5月5日,PCL春季赛常规赛第五阶段第三天比赛结束,今天打完春季赛常规赛结束,16个战队进入季后赛的名额已确定。NH战队总积分506分,总积分榜排名第一!!NH战队也是唯一一支总积分超过500分的队伍。今天最…

语音识别之其他谱图

⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计3077字,阅读大概需要3分钟 🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号&#xf…

护眼灯有没有护眼的效果?一键查看这五大护眼效果极佳的护眼台灯

在数字时代,护眼灯已成为保护视力的重要工具。但消费者常问:护眼灯有没有护眼的效果?挑选到技术过关的护眼台灯是能够很好地起到护眼效果的。本文将并重点介绍五款具有卓越护眼功能的台灯。这些精选灯具不仅在照明效果上表现出色,…

leetcode-缺失的第一个正整数-96

题目要求 思路 1.这里的题目要求刚好符合map和unordered_map 2.创建一个对应map把元素添加进去,用map.find(res)进行查找,如果存在返回指向该元素的迭代器,否则返回map::end()。 代码实现 class Solution { public:int minNumberDisappeare…

智慧公厕打造智慧城市新标杆

公共厕所作为城市基础设施的重要组成部分,直接关系到市民的生活品质和城市形象。传统的公厕管理方式存在着许多问题,如环境脏乱、清洁不及时等,给市民带来了诸多不便和不满。而智慧公厕作为一种全新的管理模式,通过物联网、大数据…

Temporary Email邮箱API发送邮件怎么配置?

Temporary Email邮箱API发送邮件的方法?如何使用? 临时邮箱因其便捷性和隐私保护的优势,越来越受到用户的青睐。而在许多场景下,我们可能需要使用临时邮箱API来发送邮件。那么,如何配置Temporary Email邮箱API发送邮件…

Docker 操作redis

命令: docker删除容器命令:docker rm 容器名称 (默认只能删除停止运行的容器) 运行redis服务端并指定窗口: docker run --name mr -p 6379:6379 -d redis redis-server --appendonly yes 运行成功之后运行docker ps 可以查看运行中的所有容器以及状态 docke rexec -it mr b…

“A”分心得:我的云计算HCIE学习之路

大家好,我是誉天云计算HCIE周末班梁同学,在誉天老师和同学们的帮助下,我终于在4月24日顺利通过了云计算3.0 HCIE的认证考试,而且获得了A,这是让我特别惊喜的,功夫不负有心人。 我日常的工作是网络运维&…

nestjs 全栈进阶--自定义装饰器

视频教程 20_nest中自定义装饰器_哔哩哔哩_bilibili nest new custom-decorator -p pnpm pnpm start:dev 在Nestjs 中我们使用了大量装饰器 decorator ,所以Nestjs 也允许我们去自定义装饰器。 1. 自定义方法装饰器 nest g decorator aaa --flat 它生产的代码…

基于web的物流管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

操作系统实战(二)(linux+C语言)

实验内容 通过Linux 系统中管道通信机制,加深对于进程通信概念的理解,观察和体验并发进程间的通信和协作的效果 ,练习利用无名管道进行进程通信的编程和调试技术。 管道pipe是进程间通信最基本的一种机制,两个进程可以通过管道一个在管道一…

618必买好物清单来袭,这些数码产品值得你考虑!

是不是很多朋友和我一样,已经迫不及待地为618好物节做好了准备,准备开启一场购物盛宴!作为一名资深家居与数码爱好者,每年618好物节时我都会尽情挑选心仪的物品,因此今天我想和大家分享一下我的618购物清单&#xff0c…