前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[译] SIGSEGV:Linux 容器中的分段错误(退出代码 139)

[译] SIGSEGV:Linux 容器中的分段错误(退出代码 139)

作者头像
CS实验室
发布于 2022-08-01 12:17:49
发布于 2022-08-01 12:17:49
8.8K00
代码可运行
举报
文章被收录于专栏:CS实验室CS实验室
运行总次数:0
代码可运行

❝翻译自 《SIGSEGV: Segmentation fault in Linux containers (exit code 139)》 原文链接:https://komodor.com/learn/SIGSEGV-segmentation-faults-signal-11-exit-code-139/ ❞

什么是 SIGSEGV

SIGSEGV,也称为分段违规或分段错误,是基于 Unix 的操作系统(如 Linux)使用的信号。它表示程序尝试在其分配的内存之外进行写入或读取,由于编程错误、软件或硬件兼容性问题或恶意攻击(例如缓冲区溢出)。

SIGSEGV 由以下代码表示:

  • 在 Unix/Linux 中,SIGSEGV 是操作系统信号 11
  • Docker 容器中,当 Docker 容器由于 SIGSEGV 错误而终止时,它会抛出退出码 139

SIGSEGV 的默认操作是进程异常终止。此外,还可能发生以下情况:

  • 通常会生成 core 文件以启用调试;
  • 出于故障排除和安全目的,SIGSEGV 信号在日志中被记录地更加详细;
  • 操作系统可以执行特定于平台的操作;
  • 操作系统可能允许进程本身处理分段错误。

SIGSEGVKubernetes 中容器终止的常见原因。但是,Kubernetes 不会直接触发 SIGSEGV。要解决此问题,您需要调试有问题的容器或底层主机。

SIGSEGV 与 SIGABRT

SIGSEGVSIGABRT 是两个可以导致进程终止的 Unix 信号。

SIGSEGV 由操作系统触发,它检测到一个进程存在内存违规,可能因此终止它。SIGABRT(信号中止)是由进程本身触发的信号。它异常终止进程,关闭并刷新打开的流。一旦被触发,就不能被进程阻塞(类似于SIGKILL,不同的是SIGKILL是由操作系统触发的)。

在发送 SIGABRT 信号之前,进程可以:

  • 调用 libc 库中的 abort() 函数,解锁 SIGABRT 信号。然后进程可以通过触发 SIGABRT 自行中止
  • 调用用于调试的 assert() 宏,如果断言为假,则使用 SIGABRT 中止程序。

退出码 139 和 134 与 Docker 容器中的 SIGSEGVSIGABRT 并行:

  • Docker 退出码 139:表示容器由于内存冲突而收到底层操作系统的 SIGSEGV
  • Docker 退出码 134:表示容器触发了 SIGABRT 并被异常终止

什么导致 SIGSEGV?

现代通用计算系统包括内存管理单元 (MMU)。MMU 可以在 Linux 等操作系统中实现内存保护,防止不同进程访问或修改彼此的内存,除非通过严格控制的 API。这简化了故障排除并使进程更具弹性,因为它们被彼此隔离开来了。

当进程尝试使用 MMU 未分配给它的内存地址时,会发生 SIGSEGV 信号或分段错误。这可能由于三个常见原因而发生:

  1. 编码错误:如果进程未正确初始化,或者如果它试图通过指向先前释放的内存的指针访问内存,则可能发生分段冲突。这将导致在特定情况下特定进程或二进制文件中的分段错误。
  2. 二进制文件和库之间的不兼容:如果进程运行的二进制文件与共享库不兼容,则可能导致分段错误。例如,如果开发人员更新了库,更改了其二进制接口,但没有更新版本号,则可能会针对较新版本加载较旧的二进制文件。这可能会导致较旧的二进制文件尝试访问错误的内存地址。
  3. 硬件不兼容或配置错误:如果在多个库中频繁发生分段错误,并且没有重复模式,这可能表明机器上的内存子系统存在问题或不正确的低级系统配置设置。

处理 SIGSEGV 错误

在基于 Unix 的操作系统上,默认情况下,SIGSEGV 信号将导致违规进程异常终止。

操作系统执行的其他操作

除了终止进程外,操作系统还可以生成 core 文件来辅助调试,也可以执行其他平台相关的操作。例如,在 Linux 上,您可以使用 grsecurity 实用程序详细记录 SIGSEGV 信号,以监控相关的安全风险,例如缓冲区溢出。

允许进程处理 SIGSEGV

在 Linux 和 Windows 上,操作系统允许进程处理它们对分段错误的响应。例如,该程序可以收集堆栈跟踪信息,其中包含处理器寄存器值和分段错误中涉及的内存地址等信息。

segvcatch 就是一个例子,它是一个支持多个操作系统的 C++ 库,能够将分段错误和其他与硬件相关的异常转换为软件语言异常。这使得使用简单的 try/catch 代码处理“硬”错误成为可能,例如分段错误。这使得软件可以识别分段错误并在程序执行期间进行纠正。

SIGSEGV 故障排除

在对分段错误进行故障排除或测试程序以避免这些错误时,可能需要故意引发分段违规以调查其影响。大多数操作系统都可以以这样一种方式处理 SIGSEGV,即使发生分段错误,它们也允许程序运行,以便进行调查和记录。

排查 Kubernetes 中常见的分段故障

SIGSEGV 故障与 Kubernetes 用户和管理员高度相关。容器由于分段违规而失败是很常见的。

但是,与 SIGTERMSIGKILL 等其他信号不同,Kubernetes 不会直接触发 SIGSEGV 信号。相反,当容器被发现执行内存违规时,Kubernetes 节点上的主机可以触发 SIGSEGV。然后容器终止,Kubernetes 检测到这一点,并可能根据 pod 配置尝试重新启动它。

当 Docker 容器被 SIGSEGV 信号终止时,它会抛出退出码 139。这可以表明:

  • 容器上运行的其中一个库中的应用程序代码存在问题;
  • 容器上运行的不同库之间不兼容;
  • 这些库与主机上的硬件不兼容;
  • 主机内存管理系统或内存配置错误的问题。

要调试和解决容器上的 SIGSEGV 问题,请执行以下步骤:

  1. 获取主机的 root 访问权限,并查看日志以查看有关有问题的容器的其他信息。SIGSEGV 错误在 kubelet 日志中如下所示:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x1bdaed0] 
  1. 尝试确定错误发生在容器映像的哪一层 —— 它可能在您的特定应用程序代码中,或在容器更底层的基础映像中。
  2. 运行 docker pull [image-id] 为由 SIGSEGV 终止的容器拉取镜像。
  3. 确保您已安装或添加调试工具(例如 curlvim)。
  4. 使用 kubectl 执行到容器中。查看您是否可以复现 SIGSEGV 错误以确认导致问题的库。
  5. 如果您已确定导致内存违规的库,请尝试修改您的镜像以修复导致内存违规的库,或将其替换为另一个库。很多时候,更新一个库 到较新版本或与主机环境兼容的版本将解决此问题。
  6. 如果您无法识别始终导致错误的库,则问题可能出在主机上。检查主机内存配置或内存硬件是否存在问题。

上述过程可以帮助您解决直接的 SIGSEGV 错误,但在许多情况下,故障排除可能会变得非常复杂,并且需要涉及多个组件的非线性调查。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CS实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[译] 容器和 Kubernetes 中的退出码完整指南
当容器终止时,容器引擎使用退出码来报告容器终止的原因。如果您是 Kubernetes 用户,容器故障是 pod 异常最常见的原因之一,了解容器退出码可以帮助您在排查时找到 pod 故障的根本原因。
CS实验室
2022/08/01
6K0
[译] 容器和 Kubernetes 中的退出码完整指南
Kubernetes 中容器的退出状态码参考指南
当容器终止时,容器引擎使用退出码来报告容器终止的原因。如果您是 Kubernetes 用户,容器故障是 pod 异常最常见的原因之一,了解容器退出码可以帮助您在排查时找到 pod 故障的根本原因。
公众号: 云原生生态圈
2024/01/23
5630
Kubernetes 中容器的退出状态码参考指南
[译] SIGTERM:Linux 容器的优雅终止(退出代码 143)
SIGTERM(信号 15)在基于 Unix 的操作系统(如 Linux)中用于终止进程。SIGTERM 信号提供了一种优雅的方式来终止程序,使其有机会准备关闭并执行清理任务,或者在某些情况下拒绝关闭。Unix/Linux 进程可以以多种方式处理 SIGTERM,包括阻塞和忽略。
CS实验室
2022/08/01
12.3K0
[译] SIGTERM:Linux 容器的优雅终止(退出代码 143)
【linux】进程创建与进程终止
上面的代码,进程11258为父进程bash,echo $?,父进程获取到的是最近一个子进程退出的退出码,前面我们提到,echo是内建命令,打印的都是bash内部的变量数据
用户11029103
2024/10/20
3480
【linux】进程创建与进程终止
解读Kubernetes常见退出码
在这篇文章中,我们将深入分析Kubernetes中的典型退出码127与137,解释它们是什么,K8s和Docker中常见的原因是什么,以及如何修复
zouyee
2024/03/04
6270
解读Kubernetes常见退出码
Linux 信号
Linux进程间通信(Inter-Process communication, IPC)机制通常分6种:
Laikee
2022/04/25
5.1K0
Linux 信号
【Linux探索学习】第十七弹——进程终止:深入解析操作系统中的进程终止机制
https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482
GG Bond1
2024/11/30
3820
【Linux探索学习】第十七弹——进程终止:深入解析操作系统中的进程终止机制
【Linux篇】操作系统揭秘:进程创建、等待与终止的无缝衔接
进程创建是操作系统中启动一个新进程的过程。通常,进程创建由现有进程发起,称为父进程。创建新进程时,操作系统会分配资源(如内存、文件句柄等),并初始化进程控制块(PCB)。父进程通过调用系统调用(如UNIX中的fork()或Windows中的CreateProcess())来创建子进程。子进程通常会继承父进程的一些资源和属性,但也可以根据需要进行修改。进程创建后,子进程会与父进程并行执行,可能有自己的执行路径,也可能通过exec()等系统调用加载新程序。
熬夜学编程的小王
2025/04/04
980
【Linux篇】操作系统揭秘:进程创建、等待与终止的无缝衔接
Linux 信号(Signal)
我们经常会使用 kill 命令杀掉运行中的进程,对多次杀不死的进程进一步用 kill -9 干掉它。你可能知道这是在用 kill 命令向进程发送信号,优雅或粗暴的让进程退出。我们能向进程发送很多类型的信号,其中一些常见的信号 SIGINT 、SIGQUIT、 SIGTERM 和 SIGKILL 都是通知进程退出,但它们有什么区别呢?很多人经常把它们搞混,这篇文章会让你了解 Linux 的信号机制,以及一些常见信号的作用。
mazhen
2023/11/24
1.4K0
Linux 信号(Signal)
内核转储的设置
当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做 Core Dump(中文有的翻译成“核心转储”)。
嵌入式与Linux那些事
2023/02/13
2K0
内核转储的设置
【Linux篇】理解信号:如何通过信号让程序听从操作系统的指令
信号的产生是现代通信系统中的基础,它涉及将信息从一个地方传递到另一个地方。在通信过程中,信号扮演着至关重要的角色,它是信息的载体。信号的生成可以通过不同的方式实现,包括电磁波的调制、音频信号的转换等。理解信号的产生过程有助于我们掌握如何高效地传递信息。在此基础上,我们能够进一步探讨信号的处理与优化,确保信息能够准确、迅速地到达目的地。
熬夜学编程的小王
2025/04/27
1010
【Linux篇】理解信号:如何通过信号让程序听从操作系统的指令
Kubernetes故障排查指南-分析容器退出状态码
大家在使用 Kubernetes 时,会遇到创建Pod失败,这时会分析什么原因导致创建Pod失败?
YP小站
2020/06/24
3.8K0
【Linux】:进程信号(信号概念 & 信号处理 & 信号产生)
🚀 信号是 Linux 系统提供的一种向指定进程发送特定事件的方式,进程会对信号进行识别和处理。
IsLand1314
2024/11/19
3080
【Linux】:进程信号(信号概念 & 信号处理 & 信号产生)
【linux学习指南】Linux进程信号产生(三) 硬件异常&&除零出错?&&野指针异常?&&core文件
硬件异常被硬件以某种⽅式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执⾏了除以0的指令,CPU的运算单元会产⽣异常,内核将这个异常解释为SIGFPE信号发送给进程。再⽐如当前进程访问了⾮法内存地址,MMU会产⽣异常,内核将这个异常解释为SIGSEGV信号发送给进程。
学习起来吧
2024/12/01
1520
【linux学习指南】Linux进程信号产生(三) 硬件异常&&除零出错?&&野指针异常?&&core文件
Linux进程信号【信号产生】
在 Linux 中,进程具有独立性,进程在运行后可能 “放飞自我”,这是不利于管理的,于是需要一种约定俗成的方式来控制进程的运行,这就是 进程信号,本文将会从什么是进程信号开篇,讲述各种进程信号的产生方式及作用
北 海
2023/07/01
5630
Linux进程信号【信号产生】
【进程信号】二、信号的产生
​ 我们平时在命令行中使用 ctrl + c 等组合键,为什么就能中断一个前台进程呢❓❓❓
利刃大大
2025/04/09
450
【进程信号】二、信号的产生
Linux:进程信号(一.认识信号、信号的产生及深层理解、Term与Core)
上次结束了进程间通信的知识介绍:Linux:进程间通信(二.共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量
是Nero哦
2024/07/25
3290
Linux:进程信号(一.认识信号、信号的产生及深层理解、Term与Core)
【团队分享】刀锋铁骑:常见Android Native崩溃及错误原因
王竞原,负责网游刀锋铁骑项目,高级开发工程师,使用C++已有10年,非常喜欢C++,特别是C++11。希望能与广大的C++爱好者多交流。 一、什么是Android的C/C++ NativeCrash Android上的Crash可以分两种: 1、Java Crash java代码导致jvm退出,弹出“程序已经崩溃”的对话框,最终用户点击关闭后进程退出。 Logcat 会在“AndroidRuntime”tag下输出Java的调用栈。 2、Native Crash 通过NDK,使用C/C++开发,导致
腾讯Bugly
2018/03/22
4.3K0
【团队分享】刀锋铁骑:常见Android Native崩溃及错误原因
iOS_Crash 异常类型
断点异常类型表示跟踪陷阱(trace trap)中断了该进程。跟踪陷阱使附加的调试器有机会在进程执行的特定点中断进程。 在 ARM 处理器上显示为 EXC_BREAKPOINT(SIGTRAP) 在 x86_64 处理器上显示为 EXC_BAD_INSTRUCTION(SIGILL)
mikimo
2023/10/18
2.3K0
【Linux信号】一:信号的概念、信号的产生
信号在生活中随处可见,比如体育比赛中使用的信号枪、我给你传递一个眼神(你懂的哈哈哈),等等。这些信号都有一些共同点:一是简单;而是不能携带大量信息;三是满足某个特设条件才发送。
mindtechnist
2024/08/08
2600
【Linux信号】一:信号的概念、信号的产生
推荐阅读
相关推荐
[译] 容器和 Kubernetes 中的退出码完整指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验