【问题记录】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
  • 检查变量值:你可以使用print命令来检查变量的值。只需指定变量名即可查看其当前值。
    • (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 文件的权限和内容是敏感操作,可能会影响系统的稳定性和安全性。务必小心谨慎,并确保了解所做更改的影响。

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

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

相关文章

【云原生】Docker镜像的创建,Dockerfile

一、Docker镜像的创建 创建镜像有三种方法&#xff0c;分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it --name web centos:7 /bin/…

UDS之27服务

SecurityAccess&#xff08;0x27&#xff09;—— 安全访问 这个服务的目的是为那些限制访问&#xff0c;以及和排放、安全相关的一些服务和数据提供一些访问权限来保护数据。 此服务执行步骤如下&#xff1a; &#xff08;1&#xff09;Client请求一个种子&#xff08;Seed…

可证明安全初步(Provable Security Basics)

Speecher: Bingsheng Zhang 这一系列的课程&#xff0c;为了介绍一些基础&#xff0c;弥补一些上密码学课和看论文的Gap。 历史上的密码学是art&#xff0c;就像鲁班锁&#xff0c;看着很精妙&#xff0c;但是没有证明。 1970s以来&#xff0c;逐渐发展成Science。 定义和模…

Vue3 axios数据请求封装

Vue3 axios数据请求封装 环境&#xff1a;vue3tsvite 首先在项目目录下安装axios 运行 npm install axios 成功后在package.json文件会显示。 目录&#xff1a; request.ts文件代码&#xff1a; import axios from axiosconst request axios.create({baseURL:https://api.…

20230721 Essex UK, Dongbing Gu 公开讲座--机器人前沿

个人主页&#xff1a; https://www.essex.ac.uk/people/GUDON81301/dongbing-gu 机器人领域任务的特点&#xff1a;dull, dirty, dangerous tasks in remote spaces 机器鱼&#xff1a; 实时港口环境监测 机器鱼群探索算法 化学传感器 水面声呐定位系统/SLAM/通信问题 Robotic …

SpringBoot中使用测试框架MockMvc来模拟HTTP请求测试Controller接口

场景 Java中进行单元测试junit.Assert断言、Mockito模拟对象、verify验证模拟结果、Java8中lambda的peek方法使用&#xff1a; Java中进行单元测试junit.Assert断言、Mockito模拟对象、verify验证模拟结果、Java8中lambda的peek方法使用_assert java8_霸道流氓气质的博客-CSD…

【MySQL】centos 7下MySQL的环境搭建

从本期博客开始我们正式进入到数据库的学习&#xff0c;在学习数据库时所用到的工具是Linux环境下的MySQL 目录 一、检查环境中是否装有MySQL 二、获取MySQL官方yum源 三、配置MySQL官方yum源 四、一键安装MySQL 五、启动mysql服务 六、登录MySQL 七、修改mysql配置文件…

智慧园区电力监控解决方案

1、概述 电力监控系统实现对园区变电站、配电房内断路器、变压器、柴油发电机以及其它重要设备进行监视、测量、记录、报警等功能&#xff0c;并与保护设备和远方控制中心及其他设备通信&#xff0c;实时掌握园区变电站和配电房运行状况&#xff0c;快速排除故障&#xff0c;保…

redis中使用bloomfilter判断元素是否存在

一 bloomfiler的作用 1.1 bloomfilter的作用 由一个初始值为0的bit数组组成&#xff0c;和多个hash函数构成&#xff0c;用来判断集合中是否存在某个元素。 一个很长的二进制数组&#xff08;00000000&#xff09;一系列随机hash算法映射函数。主要用于判断一个元素是否存在…

【C++】类和对象-封装

1.属性和行为作为整体 2.示例2-设计学生类 3.访问权限 4.class和struct的区别 5.成员属性设置为私有 6.设计案例1-立方体类 在main函数前重新补上isSame函数 在Cube类里面添加issamebyclass&#xff0c;利用成员函数判断两个立方体是否相等 自己写的代码&#xff1a; #in…

(四)RabbitMQ高级特性(消费端限流、利用限流实现不公平分发、消息存活时间、优先级队列

Lison <dreamlison163.com>, v1.0.0, 2023.06.23 RabbitMQ高级特性&#xff08;消费端限流、利用限流实现不公平分发、消息存活时间、优先级队列 文章目录 RabbitMQ高级特性&#xff08;消费端限流、利用限流实现不公平分发、消息存活时间、优先级队列消费端限流利用限流…

jenkins

Gitlab添加钩子 测试钩子 添加完成后&#xff0c;下面会出现钩子选择。点击test中的&#xff0c;push event。 出现successful&#xff0c;既添加成功。 如果添加失败&#xff0c;报错&#xff0c;更改Network

智能安全配电装置应用场景有哪些?

安科瑞 华楠 一、应用背景 电力作为一种清洁能源&#xff0c;给人们带来了舒适、便捷的电气化生活。与此同时&#xff0c;由于使用不当&#xff0c;维护不及时等原因引发的漏电触电和电气火灾事故&#xff0c;也给人们的生命和财产带来了巨大的威胁和损失。 为了防止低压配电…

妙记多 Mojidoc PC端(Mac 端+windows端)Beta版本正式上线!

你们呼唤了无数次的妙记多 Mojidoc PC客户端 Beta版本正式上线啦&#xff01; 感谢300位妙友积极参与内测&#xff0c;给予了我们很多非常有效的意见和建议&#xff01;我们会根据用户反馈不断优化和修复相关功能&#xff0c;在此感谢妙友们一直以来的支持&#xff5e; PC端拥…

Spring(10) 生成和替换Banner启动图案

目录 1.背景2.推荐网站3.如何集成到spring项目中4.效果展示 1.背景 我们在启动 Spring 项目的时候经常会看到一个 Spring 字样的启动图案。如下所示&#xff1a; 如果我们也想根据我们的内容生成这样的图案&#xff0c;应该怎么操作呢&#xff1f; 2.推荐网站 可以生成这种图…

Qt Core学习日记——第四天QMetaEnum(下)

类定义&#xff1a; 成员变量就只有QMetaObject *mobj和uint handle&#xff0c;handle同样用于计算在qt_meta_stringdata_XTest的位置 成员函数&#xff1a; 接下以test类进行函数讲解 test.h #pragma once #include <qobject.h> #include <QFlags> class X…

C语言非常道 6.4习题解答

关于 #include “stdarg.h” 相关知识小结&#xff1a; 函数&#xff1a;tppedef va_list char * ; va_list al; va_start(al, fmt) 使 al 指向变参函数中最后一个已知参数&#xff08;从右往左数的第一个已知参数&#xff09; va_arg(两个参数&#xff09;&#xff0c;第一个…

SpringBoot中配置文件的加载

springboot 启动会扫描一下位置的application.properties或者application.yml文件作为springboot的默认配置文件 file:./config/(项目根目录config文件夹下的配置文件) file:./(项目根目录下的配置文件) classpath:/config/(resources目录config文件下的配置文件) classpat…

【Android】Ubuntu20.04编译Android 13并用模拟器运行

前言 一直好奇Android系统是怎么定制的&#xff0c;直到亲自走一遍Android系统编译流程才发现并没想象的复杂。 这就跟app开发一样&#xff0c;Google官方其实都提供了平台、文档、IDE及一些工具&#xff0c;咱们只要按照官方提供的指南来操作就行了。 如果Android没有提供这…