【银河麒麟】unzip程序卡住,处理机制详解,附代码

news2024/10/6 7:07:46

1.服务器环境以及配置

【机型】

处理器:

HUAWEI,Kunpeng 920

内存:

400G+

【内核版本】

4.19.90-23.18.v2101.ky10.aarch64

【OS镜像版本】

银河麒麟高级服务器操作系统V10-SP1-0711-arm

【第三方软件】

docker

2.问题现象描述

一台k8s服务器里面的容器java程序启动shell脚本执行解压unzip命令,进程一直处于sleep状态,没有执行解压,一直卡着。

3.问题分析

通过gdb查看,可看到unzip进程栈为:

可看到阻塞在fgets调用read上,此时read通过系统调用到了内核,所以推测为阻塞在内核阶段。

此时查看进程内核栈为:

根据内核栈,可知unzip进程卡在了读取管道数据上,此状态可以用以下方式进行模拟:

即直接cat 标准输入,则可直接模拟问题,至此,直接原因可明确:unzip进程卡在了读取管道数据上。

但问题根本原因,以及正常是怎样的流程,需要继续分析:

查看现场文件描述符信息如下:

查看确认0,1,2描述符继承自父进程。

通过cat测试相关描述符,发现描述符内容很多。

本地java启动shell脚本启动unzip可看到同样的描述符继承关系:

java程序如下:

public static void main(String[] args) throws Exception {

String command = "sh a.sh logfile.zip .";

Process process = Runtime.getRuntime().exec(command);

process.waitFor();

process.destroy();

int i = process.exitValue();

System.out.println("子进程退出值:"+i);

}

a.sh脚本为:unzip -o $1 -d $2

但本地无法模拟出现场情况,本地测试,cat 0,2管道都无内容,1有解压时的标准输出内容,与现场管道中有大量内容不同。同时,本地对unzip进程fgets函数做跟踪,无法捕捉到fgets调用,也没有捕捉到pipe_read操作。本地的所有read操作都是对文件描述符3的操作:

即从压缩文件中读数据。

推测无法复现原因与现场的环境相关,本地可能无法完全模拟现场状态,导致无法追踪到对应调用。

尝试从其它方向获得更多有用信息。

根据fgets说明:

fgets() 的原型为: char *fgets(char *s, int size, FILE *stream);

它的功能是从 stream 流中读取 size 个字 符指针变量 s 所指向的内存空间。它的返回值是个指针,指向字符串中第个字符的地址。

从函数介绍,结合前面信息可知unzip阻塞在尝试从管道读取若干数据。

本地使用head模拟读取若干数据后返回操作,如下:

可看到在未获取到对应数据之前,进程将一直阻塞在pipe_wait处。直到获取到对应数据,则返回。

由于本地无法模拟,所以无法弄清楚,unzip进程在读管道里的什么数据,以及这些数据从哪里来。

现场可尝试搭建一个测试环境,安装glibc的debuginfo包,对fgets进行调试,即可对进程核外调用有更准确的掌握,如从哪个描述符取多少数据,以及谁在往里写数据。

同时我们对java的管道规范进行了梳理,发现:

JDK中有相关说明:

By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream (). The parent process uses these streams to feed input to and get output from the subprocess. Becau se some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock. 

从JDK的说明中可以看出两点:

1.子进程的标准I/O已经被重定向到了父进程。父进程可以通过对应的接口获取到子进程的I/O

2.如果系统中标准输入输出流使用的bufffer大小有限,所有读写时可能会出现阻塞或死锁。

结合现场cat描述符异常,基本可确认现场标准输入输出流异常。

基于此,在相关编程中,java编程中推荐了多种处理方法:

1.不断的读取消耗缓冲区的数据,以至子进程不会挂起,如:

public class ProcessUtils {

public static void main(String[] args) throws IOException, InterruptedExcption{

String command = "unzip xxxx";

Process process = Runtime.getRuntime().exec(command);

readStreamInfo(process.getInputStream(), process.getErrorStream());

int exit = process.waitFor();

process.destroy();

if (exit == 0) {

log.debug("子进程正常完成");

} else {

log.debug("子进程异常结束");

}

}

/**

* 读取RunTime.exec运行子进程的输入流 和 异常流

* @param inputStreams 输入流

*/

public static void readStreamInfo(InputStream... inputStreams){

ExecutorService executorService = Executors.newFixedThreadPool(inputS

for (InputStream in : inputStreams) {

executorService.execute(new MyThread (in));

}

executorService.shutdown();

}

}

public class MyThread implements Runnable {

private InputStream in;

public MyThread(InputStream in){

this.in = in;

}

public void run() {

try{

BufferedReader br = new BufferedReader(new InputStreamReader(in,

String line = null;

while((line = br.readLine())!=null){

log.debug(" inputStream: " + line);

}

}catch (IOException e){

e.printStackTrace();

}finally {

try {

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

  1. 添加timeout超时:

public static int executeProcess(int timeout)throws IOException, InterruptedException, TimeoutException {

Process process = Runtime.getRuntime().exec(command);

Worker worker = new Worker(process);

worker.start();

try {

worker.join(timeout);

if (worker.exit != null){

return worker.exit;

} else{

throw new TimeoutException();

}

} catch (InterruptedException ex) {

worker.interrupt();

Thread.currentThread().interrupt();

throw ex;

}

finally {

process.destroy();

}

}

现场同时也发现java程序所在docker容器内存已被占满,本地模拟内存占满测试,并未复现,同时本地测试中,始终没有捕捉到unzip的fgets及pipe_read动作。所以内存占满可能并非为唯一关键因素。

4.问题总结

通过测试分析,可知问题的直接原因为java调用unzip进程阻塞在了读取管道数据调用上。但由于没有现场代码及环境,使用简单的本地java模拟无法复现对应调用流程,所以无法对其可能的触发流程做详细梳理,如果现场有条件,可安装unzip及glibc的debuginfo包,通过gdb对相关进程的fgets操作管道的流程进行捕捉,及梳理。基于此,可确认正常的调用流程。

同时现场可进一步检查unzip的0,1,2管道的情况,通过cat管道内容到文件的方式保存管道内容进行分析,如果仅仅只作为unzip的标准输入输出及错误输出,不应该有很多内容才对,是否在java编程中做了更多的操作需梳理下java的相关调用。结合unzip操作管道的正常流程,来最终确认管道异常原因。

针对java编程中父子进程管道通信可能存在的潜在问题,提供了两个可能的优化方法:

  1. 不断的读取消耗缓冲区的数据,以至子进程不会挂起
  2. 添加timeout超时,防止子进程异常阻塞导致父进程异常无法恢复。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Camera2内存泄漏修复

最近公司想要使用Camera2来替换线上的旧版相机,功能调研过程中发现Camera2在很多机器上都会有奇怪的内存泄漏,比较明显的时候可能有100M,比较常见的是表现为内存释放不及时(上涨一段时间后会有一次下降),这…

Web渗透:XXE-XML外部实体漏洞

XML External Entity (XXE) 漏洞是一种注入攻击,利用不安全的XML解析器来执行各种恶意操作,如读取本地文件、执行远程代码、发起拒绝服务攻击等;此漏洞的根本原因在于XML标准允许在文档中定义外部实体,并在解析时进行解析和替换。…

快储存,分布式文件系统,对象储存

Ceph块存储 镜像快照 快照可以保存某一时间点时的状态数据快照是映像在特定时间点的只读逻辑副本希望回到以前的一个状态,可以恢复快照使用镜像、快照综合示例 rbd create img1 --size 10G 创建镜像rbd ls 查看镜像 rbd info img1 #查看…

使用原子子表创建可重用的子组件

原子子表是一个图形对象,可帮助您在Stateflow图表中创建独立的子部件。原子子表允许: 对具有多个状态或层次结构的图表进行微小更改后,模拟速度更快。 在多个图表和模型中重复使用相同的状态或子表。 易于团队开发,适用于在同一图…

大语言模型在医疗领域的进展、应用和挑战_医疗大语言模型算法csdn

### 概述 本文综述了医学领域大型语言模型(LLM)的进展、应用和面临的挑战。大型语言模型如ChatGPT在理解和生成人类语言方面显示出了显著的能力,引起了广泛关注。在医学领域,研究人员正致力于利用LLM支持各种医疗任务&#xff0c…

文华财经盘立方博易大师主图指标公式大全源码均线

文华财经盘立方博易大师主图指标公式大全源码均线: N:3; EMA25:EMA(C,25),COLORRED,LINETHICK2; EMA70:EMA(C,70),COLORGREEN,LINETHICK2; EMA450:EMA(C,450),COLORYELLOW,LINETHICK2; CONDA1:EMA25>EMA70&&C>HV(H,6)&&C>EMA450&…

C语言 | Leetcode C语言题解之第179题最大数

题目&#xff1a; 题解&#xff1a; long cmp(int *x, int *y) {unsigned long sx 10, sy 10;while (sx < *x) {sx * 10;}while (sy < *y) {sy * 10;}return sx * (*y) (*x) - sy * (*x) - (*y); }char *largestNumber(int *nums, int numsSize) {qsort(nums, numsSi…

Linux C 程序 【01】最小程序

1.开发背景 基于 RK3568 平台的基础上&#xff0c;编译一个在系统上运行的最小程序。 2.开发需求 由于 RK3568 作为宿主机&#xff0c;在上面编译程序比较慢&#xff0c;所以还是采用在 Ubuntu 下交叉编译后再拷贝到宿主机上运行。 设计实验&#xff1a; 1&#xff09;搭建 M…

数据分析必备:一步步教你如何用matplotlib做数据可视化(14)

1、Matplotlib 图像 Matplotlib包中的图像模块提供加载&#xff0c;重新缩放和显示图像所需的功能。Pillow库支持加载图像数据。Matplotlib仅支持PNG图像。如果本机读取失败&#xff0c;下面显示的命令将回退到Pillow。 此示例中使用的图像是PNG文件&#xff0c;但请记住数据的…

AFLNet入门教学——测试RTSP协议实现Live555(Ubuntu)

1、简介 本文旨在使用AFLNet对RTSP协议实现Live555进行模糊测试。实验环境为&#xff1a;Ubuntu22.04.4AFLNet安装参考&#xff1a;AFLNet入门教学——安装&#xff08;Ubuntu22.04.4&#xff09;-CSDN博客 2、安装Live555 本次实验采取的是live555在2018年8月28日上传的版本…

数据库怎么同步

数据库要怎么同步呢&#xff0c;有很多方法&#xff0c;看你用什么数据库&#xff0c;如果是Sqlserver,你要数据库同步&#xff0c;那么可以使用自带的订阅发布&#xff0c;订阅发布应该是不错的方法&#xff0c;但是我上次要配置双向同步&#xff0c;它的对等发布好像没部署成…

【LeetCode】四、栈相关:有效的括号 + 下一个更大的元素

文章目录 1、栈结构2、Java中的栈3、leetcode20&#xff1a;有效的括号4、leetcode496&#xff1a;下一个更大元素 1、栈结构 和队列相反&#xff0c;栈先进后出 时间复杂度&#xff1a;访问、插入、删除都在栈顶进行操作&#xff0c;时间复杂度为O(1)&#xff0c;搜索需要遍…

【自监督-MIM】系列方法学习二

Masked image modeling 是一种训练深度学习模型的技术,尤其是在视觉领域,类似于自然语言处理中的掩码语言建模(Masked Language Modeling)。它通过在输入图像中随机遮挡(或称为掩码)部分区域,然后训练模型来预测这些被遮挡部分的内容,从而提高模型的视觉理解能力。 Ma…

常见的字符串函数(包含头文件string.h)和字符函数(2)

八. strstr函数 1.strstr的定义 char *strstr( const char *str1, const char *str2 ); ->1. strstr查找子串(str2)在字符串(str2)中第一次出现的位置&#xff0c;记录并返回该位置的指针&#xff0c;如果找不到&#xff0c;则返回NULL ->2. str1&#xff1a;查找字符…

Java毕业设计 基于SSM vue药店管理系统小程序 微信小程序

Java毕业设计 基于SSM vue药店管理系统小程序 微信小程序 SSM 药店管理系统小程序 功能介绍 用户 登录 注册 首页 药品信息 药品详情 加入购物车 立即购买 收藏 购物车 立即下单 新增收货地址 我的收藏管理 用户充值 我的订单 留言板 管理员 登录 个人中心 修改密码 个人信息…

【深度学习】python之人工智能应用篇--跨模态生成技术

跨模态生成技术概述 跨模态生成技术是一种将不同模态的数据&#xff08;如文本、图像、音频、视频等&#xff09;进行融合和转换的技术。其目标是通过将一个模态的数据作为输入&#xff0c;生成与之对应的另一个模态的输出。这种技术对于突破单一模态的局限性&#xff0c;提高…

【九】【QT开发应用】WebRTC的sigslot源码和使用WebRTC的sigslot使用编写信号槽

WebRTC&#xff08;Web Real-Time Communication&#xff09; 是一个开源项目&#xff0c;提供实时通信能力&#xff0c;广泛应用于视频、音频和数据传输。在WebRTC的实现中&#xff0c;sigslot库用于信号和槽机制&#xff0c;以实现事件驱动的编程模型。 WebRTC的sigslot部分…

如何精准分析人形机器人运动数据?

全球“机器换人”进程加速,人形机器人有望成为AI下一个重要落地应用场景;EtherCAT-Analyzer具备分析人形机器人所有关节和电池与主站的通讯信息,快速掌握节点网络状态! 前言 随着人形机器人行业的发展及《中国制造2025》的全面实施,传统的脉冲模式控制很大程度上制约了机…

一个例子理解傅里叶变换的计算过程

假设我们有一个简单的信号&#xff0c;由两个不同频率的正弦波组成&#xff0c;我们希望通过傅里叶变换来分析其频谱。 示例信号 假设我们有一个信号 &#xff1a; 这个信号由两个频率成分组成&#xff1a;一个50 Hz的正弦波和一个120 Hz的正弦波&#xff0c;后者的振幅是前者…

用一个实例看如何分享大量照片 续篇二,关于Exif (Exchangeable Image File) - 可交换图像文件

续篇二&#xff1a;说说关于照片隐含的 Exif (Exchangeable Image File) 可交换图像文件 数码照片的Exif 参数有很多&#xff0c;重要的Exif信息&#xff1a;拍摄日期、时间、拍摄器材、GPS信息。 当然这主要对自己的档案有意义&#xff0c;如果放到网上还是建议抹去这些信息。…