【问题记录】Ubuntu 22.04 环境下,程序报:段错误(核心已转储)怎么使用 core 文件和GDB调试器 解决?
目录
环境
问题情况
解决思路
原因分析
解决方法
番外知识
环境
- VMware® Workstation 16 Pro (版本:16.1.2 build-17966106)
- ubuntu-22.04.2-desktop-amd64
问题情况
- 本人在运行百万并发的服务端程序时,程序运行报:段错误(核心已转储),导致程序异常退出,如下
解决思路
- 首先要确定核心转储文件的生成路径和大小限制。然后使用调试器(如 GDB)来分析核心转储文件和堆栈跟踪信息后,修复代码中导致“段错误”的原因。
原因分析
1.什么是段错误?
- 段错误(Segmentation Fault)是一种常见的程序错误,通常在访问无效的内存地址时发生。当程序试图访问一个不属于它的内存段时,操作系统会发送一个信号(SIGSEGV(段错误信号))给程序,称为段错误。
2.可能产生段错误的情况
- 内存访问错误:最常见的原因之一是程序试图访问无效的内存地址或未初始化的指针。这可能是由于代码错误、缓冲区溢出或内存越界等造成的。当程序尝试访问系统不允许访问的内存区域时,操作系统会引发段错误。
- 无效的指令或操作:另一个常见原因是程序执行了无效的指令或操作。这可能是由于编译错误、错误的代码逻辑或架构不兼容性等引起的。当处理器尝试执行无效的指令或操作时,会导致段错误。
- 动态内存分配问题:使用动态内存分配(如
malloc
或new
)时,如果出现内存泄漏、重复释放已释放的内存或访问已释放的内存等问题,可能导致段错误。这些问题可能是由于错误的内存管理导致的。- 栈溢出:如果程序的栈空间超出了其允许的范围,例如无限递归调用或大量局部变量使用导致的栈溢出,会产生段错误。
- 库或依赖项问题:有时,段错误可能是由于使用损坏的库、不兼容的版本或缺少的依赖项引起的。库的错误使用或配置问题可能导致段错误。
- 硬件问题:虽然比较罕见,但硬件故障(如内存损坏)也可能导致程序报告段错误并生成核心转储。
3.核心已转储是转储到那儿?
- 当程序发生段错误时,操作系统会生成一个名为
core
或core.<进程ID>
的核心转储文件,其中包含了程序崩溃时的内存映像和其他相关信息。这个core文件通常会被转储到当前工作目录下。- 但我的 core 文件并没有生成到程序的工作目录下,看下面解决...
解决方法
1.检查操作系统的核心转储文件(core dump file)生成设置
- 使用命令
ulimit -a
查看当前的核心转储文件大小限制和其他限制信息- 查找输出中的"core file size"(核心转储文件大小)字段,红框中的
0
表示当前禁用了核心转储文件的生成。可以更改这个限制来启用核心转储文件的生成。
2.更改 "core file size”字段 的限制来启用核心转储文件的生成
使用ulimit -c unlimited
命令可以将core文件的大小限制设置为无限制,但通过(不推荐)ulimit
命令设置的参数仅在当前 shell 进程生效,也就是当前会话。一旦关闭终端窗口,设置将被重置为默认值。因此,这种修改并不是永久性的。- 如果想要在系统级别永久修改core文件的生成大小限制,需要进行操作系统的配置更改。可以通过修改
/etc/security/limits.conf
文件来设置core文件大小限制。添加或修改下面两行:
- * soft core unlimited
- * hard core unlimited
- 重启虚拟机,重新加载系统的参数配置,以确保更改生效(重启命令: sudo reboot)
3.话不多说,直接测试一下
- 不想跑服务端程序了,太费时了,直接写一个测试栗子,代码如下:
- 运行该测试栗子后,并没有在工程目录下生成 core 文件。
4.确定一下 core 文件的生成路径
- 查找资料说Linux 内核有一个参数
kernel.core_pattern
,用于指定生成核心转储文件时的文件名和路径模式,相关的配置文件为/proc/sys/kernel/core_pattern
。而在 Linux 中,可以使用sysctl
命令来检查和更改核心转储文件的生成路径限制。- 然后使用
sysctl kernel.core_pattern
命令来查看当前的核心转储文件生成路径。它输出了下面一行内容:
- kernel.core_pattern = |/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
- 上面这一行是啥意思呢,解释如下:
|/usr/share/apport/apport
: 它是一个特殊的核心转储处理程序(core dump handler),它是一个用于收集和报告故障的工具。当进程收到SIGSEGV
或类似的信号时,内核将使用kernel.core_pattern
中指定的处理程序来处理和处理核心转储文件。%p
: 进程 ID。%s
: 目前正在运行的线程 ID。%c
: 产生核心转储文件的信号代码。%d
: 序列号,用于确保在同一目录中生成的核心转储文件具有唯一的名称。%P
: 父进程 ID。%u
: 用户名。%g
: 组名。%E
: 产生核心转储文件的可执行文件全路径。- 具体而言,
/usr/share/apport/apport
是一个用于 Ubuntu 系统的工具,它可以收集有关崩溃和故障的信息,并生成相应的错误报告。
5.修改 core 文件的生成路径
- 可以使用
sudo sysctl -w kernel.core_pattern=<path_to_directory>/core
命令将其恢复为期望的路径。确保<path_to_directory>
是一个有效的目录路径。比如
- sudo sysctl -w kernel.core_pattern=core
- 重新编译一下,在当前目录下生成了
core.<进程ID>
的核心转储文件,如下- 注意:以上方式修改
kernel.core_pattern
的值只在运行时生效,并不是永久的,在系统重启后,该更改将被重置为默认值。- 可以了解最后一节“番外知识”
6.使用调试工具 gdb 来加载和分析 core 文件
- 生成核心文件:使用 gcc 编译记得加 -g 命令。
- 加载核心文件:使用gdb命令行加载核心文件,将核心文件加载到调试环境中。
- gdb <可执行文件路径> <核心文件路径>
- 查看堆栈回溯:运行gdb后,使用
bt
命令(或backtrace
)来查看堆栈回溯,它将显示程序在崩溃时的函数调用链。
- (gdb) bt
- 检查变量值:你可以使用
- (gdb) print variable_name
- 跳转到特定帧:使用
frame
命令可以在堆栈帧之间进行导航,并查看在特定帧上的堆栈信息。帧编号通常是从0开始按逆序分配的,也就是最底部帧的编号是0。
- (gdb) frame frame_number
- 分析原因:分析堆栈回溯和变量值,可以帮助你定位程序崩溃的原因。一般情况下,最底部的堆栈帧提供了最初崩溃的位置。
- 操作如下:说明 *P 未初始化
番外知识
1.对 /proc/sys/kernel/core_pattern 可以添加可写权限吗?
- 答案是不可以。默认权限如下(所有者具有读写权限,组用户和其他用户只有读取权限)。
- 对于
/proc/sys/kernel/core_pattern
文件,不能直接添加可读权限。这是因为/proc
目录和其下的文件是虚拟文件系统(procfs
)的一部分,用于提供对内核和进程信息的访问,它们的权限和所有权是由内核控制的,而不受Linux文件系统权限模型的限制。- 在
/proc
目录中,每个文件和目录的权限通常被设置为只读,不允许用户直接修改它们的权限。这是为了确保提供的信息的完整性和一致性,并防止对内核和进程状态的非授权更改。- 因此,无法通过常规的
chmod
命令或其他方式直接向/proc/sys/kernel/core_pattern
添加可读权限或更改其权限。尝试执行类似以下命令时会出现错误:
- sudo chmod +w /proc/sys/kernel/core_pattern
- 你会收到“Operation not permitted”或“不允许的操作”类似的错误消息。
2.在系统重启后,对
/proc/sys/kernel/core_pattern
文件的更改为什么被重置为默认值?
- 这是因为
/proc/sys/
目录中的文件是在内核启动期间动态生成的,其值来自于内核参数或其他系统设置。在系统重启时,这些文件会重新加载为其默认值或由某些配置文件指定的值。
3.怎么实现永久性修改
/proc/sys/kernel/core_pattern
文件呢?(这条有问题)
- 编辑
/etc/sysctl.conf
文件:(这种方式不太好,每次系统重启后要执行一下 sudo sysctl -p 命令才会修改/proc/sys/kernel/core_pattern的值)
- 可以编辑
/etc/sysctl.conf
文件,将核心转储文件模式的修改添加到该文件中,添加内容如下:
- kernel.core_pattern = core
- 在保存并退出文件后,使用以下命令重新加载配置,使新的核心转储文件模式生效:
- sudo sysctl -p
- 创建并编辑系统启动脚本:可以编写一个脚本,以在系统启动时将核心转储文件模式设置为所需的值。将脚本放置在适当的位置,例如
/etc/init.d/
目录,并设置为在系统启动时执行。(测试了没有用)
- 创建启动脚本文件:在所选择的目录中创建一个新文件
- sudo vim /etc/init.d/my_startup_script.sh
- 编写启动脚本:在脚本中添加如下内容,保存成功并退出。
- #!/bin/bash
- echo "core" >> /proc/sys/kernel/core_pattern
- exit 0
- 赋予脚本执行权限:使用以下命令为启动脚本文件赋予执行权限
- sudo chmod +x /etc/init.d/my_startup_script.sh
- 配置启动脚本的执行:将启动脚本添加到系统的启动过程中,以确保在系统启动时执行
- sudo update-rc.d my_startup_script.sh defaults
- 若要禁用脚本的启动,可以使用以下命令(了解)
- sudo update-rc.d -f my_startup_script.sh remove
注意
- 需要注意的是,更改
/proc/sys/kernel/core_pattern
文件的权限和内容是敏感操作,可能会影响系统的稳定性和安全性。务必小心谨慎,并确保了解所做更改的影响。
相关文章:

【问题记录】Ubuntu 22.04 环境下,程序报:段错误(核心已转储)怎么使用 core 文件和GDB调试器 解决?
目录 环境 问题情况 解决思路 原因分析 解决方法 番外知识 环境 VMware Workstation 16 Pro (版本:16.1.2 build-17966106)ubuntu-22.04.2-desktop-amd64 问题情况 本人在运行百万并发的服务端程序时,程序运行报:…...
9 Linux实操篇-实用指令
9 Linux实操篇-实用指令 文章目录 9 Linux实操篇-实用指令9.1 指定和修改运行级别-init/systemctl9.2 找回root密码9.3 Linux的指令说明9.3 帮助类-man/help9.4 文件目录类-pwd/ls/cd/mkdir/...9.5 时间日期类-date/cal9.6 搜索查找类-find/locate/which/grep9.7 压缩和解压类-…...

Hbase基础概念
HBase 一、HBase的数据模型1.HBase数据存储结构2.HBase存储概念3.HBase基本架构 二、HBase Shell1.DDL(Data Definition Language)1.namespace2.table 2.DML(Data Manipulation Language)1.写入数据2.读取数据3.删除数据 三、HBase组成架构1. Master架构…...
JTS-Angle角度类
目录: 获取AB连线与正北方向的角度求距离此点一定距离、一定夹角的点经纬度判断point点 在线段startPoint-etartPoint的左侧或者右侧米转换为弧度弧度转换为米 定义Point点 public class LatLngPoint {final static double RC 6378137;final static double RJ …...

pytest---环境切换(base-url)
前言 前面小编介绍了如何通过pytest的插件来实现自动化测试的环境的切换,当时使用的方法是通过钩子函数进行获取命令行参数值,然后通过提前配置好的参数进行切换测试环境地址,今天小编再次介绍一种方法,通过pytest的插件ÿ…...

linux跑代码,程序终止了,但资源没有释放。
linux跑代码,程序终止了,但资源没有释放。 程序终止,但是资源没有释放. kill -9 5062完成。 linux终止进程...

数据结构--线性表2-1
目录 一、线性结构的定义 二、线性表的表示 三、顺序表的实现(或操作) 1、修改: 2、插入: 四、顺序表的运算效率分析:时间效率分析: 一、线性结构的定义 若结构时非空有限集,则有且仅有一个…...

网访问内网机器:基于frp的内网穿透
随缘更新些我自己的博客网站里的文章吧 因为经常需要远程访问自己的机器,所以写一个博客记录一下 公网访问内网机器:基于frp的内网穿透 从公网中访问自己的私有设备向来是一件难事儿。 1. 为什么需要内网穿透? A. 计算机网络 如何在自己的机…...

【Spring框架】Spring读取与存储综合练习
练习 在 Spring 项⽬中,通过 main ⽅法获取到 Controller 类,调⽤ Controller ⾥⾯通过注⼊的⽅式调⽤ Service 类,Service 再通过注⼊的⽅式获取到 Repository 类,Repository 类⾥⾯有⼀个⽅法构建⼀个 User 对象,返…...

Python实现指定区域桌面变化监控并报警
在这篇博客中,我们将使用Python编程语言和一些常用的库来实现一个简单的区域监控和变化报警系统。我们将使用Tkinter库创建一个图形界面,允许用户选择监控区域,并使用OpenCV库进行图像处理和相似性比较,以检测区域内的变化&#x…...

【数据结构】实验五:栈
实验五 栈 一、实验目的与要求 1)熟悉栈的类型定义和基本操作; 2)灵活应用栈解决具体应用问题。 二、实验内容 1、判断回文数,回文是指正读反读均相同的字符序列,如“1221”和“12321”均是回文,但“…...

⚡️⚡️Java多线程编程的高效、安全实践
⚡️ Java多线程编程的高效、安全实践⚡️ ☀️ 1 摘要☀️2 多线程编程基础☀️ 3 线程同步与互斥☀️ 4 并发集合类与原子操作☀️ 5 线程池与执行器框架☀️ 6 并发编程的最佳实践🌄 7 总结 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客…...

【云原生】Docker私有仓库registry
目录 1)用docker容器运行registry私有仓库服务。 2)运行私有仓库服务 3)镜像重命名(要上传的镜像名需要注明私仓的ip) 4)编辑docker配置文件(因为默认是拉取docker官方的镜像,需要重新指定) 5)其他dock…...

第十四届蓝桥杯大赛青少年省赛C++组试题真题 2023年5月
一、选择题 第 1 题 单选题 C中,bool类型的变量占用字节数为 ( )。 A. 1 B. 2 C. 3 D. 4 第 2 题 单选题 以下关于C结构体的说法,正确的是 ( )。 A. 结构体中只能包含成员变量,不能包含成员函数 B. 结构体不能从另一个结构体继承 …...

GAN论文精读
标题:Generative Adversarial Nets 摘要: 简写:作者提出了一个framework通过一个对抗的过程,在这里面会同时训练两个模型。 第一个模型为生成模型G,是用来抓住整个数据的分布 第二个模型为辨别模型D,是用来估计一个样本是否从G中产生。 …...
数据结构:计数排序(详解)
思路详解: 1 找到数组中的最大值、最小值 2 开辟一个统计每个数据出现次数的数组(总个数是最大值-最小值1,因为下标范围是0~最大值-最小值,闭区间统计个数要1) 3 遇到一个元素,在此元素-最小值作为下标的…...

1 请使用js、css、html技术实现以下页面,表格内容根据查询条件动态变化。
1.1 创建css文件,用于编辑style 注意: 1.背景颜色用ppt的取色器来获取: 先点击ppt的形状轮廓,然后点击取色器,吸颜色,然后再点击形状轮廓的其他轮廓颜色,即可获取到对应颜色。 2.表格间的灰色线…...

react-native项目安卓版本升级 compileSdkVersion 29->31
因为 react-native-ble-manager添加过程及碰到的问题 依赖 https://github.com/innoveit/react-native-ble-manager 参考:https://blog.csdn.net/withings/article/details/71378562 iOS 按react-native-ble-manager 文档在 【Info.plist】加了key之后能正常使用…...

【学习笔记】目标跟踪领域SOTA方法比较
目录 前言方法1 TraDeS:2 FairMOT:3 SMILEtrack:4 ByteTrack: 前言 常用于行人跟踪的多目标跟踪数据集包括:MOT 15/16/17/20、PersonPath22等… 为更好比较现有SOTA算法的检测性能,本博客将针对在各数据集上表现较优的算法模型进行介绍。(表…...

机器学习 深度学习编程笔记
sigmoid函数 def sigmoid(x):return 1.0 / (1np.exp((-x)))定义最小平方和损失函数 loss torch.nn.MSELoss()线性回归编程 如果不加噪音就成了正常的线性函数了,所以要加噪音。 torch.normal(0, 0.01, y.shape)torch.normal(0, 0.01, y.shape)是一个用于生成服从…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...