当前位置: 首页 > news >正文

[deadlock]死锁导致的设备登录无响应问题

[deadlock]死锁导致的设备登录无响应问题

  • 一、问题现象
  • 二、初步观察
  • 三、继续深挖
    • 查看netlink相关信息
    • 查看warnd进程栈
  • 四、再接再厉
    • 查看warnd 用户栈
  • 后记

一、问题现象

实验室一台压力测试设备突然无法登录,无论web页面,ssh或者telnet登录,都是输入用户名密码后卡在哪里,无法进入管理页面。
如果这样子的话,根本无法调试。幸运的是,有个之前就打开的shell窗口可以使用。这给我们分析调试提供了方便。

二、初步观察

在shell中查看现存和hang住的命令行进程,看看有什么线索。

/var/log# ps | grep cli2812 root      720m S    cli admin 1 admin telnet(10.10.20.11)
15126 root      720m S    cli admin 1 admin telnet(10.10.20.11)
15264 root      720m S    cli admin 0 admin console
21947 root     16448 S    grep cli

这里有3个cli进程,有除了2812是我们当前在使用的,剩下两个都是无响应的。查看进程的内核栈信息。

/var/log# cat /proc/15264/stack
[<ffffffff8080a819>] netlink_attachskb+0x189/0x1d0
[<ffffffff8080a991>] netlink_unicast+0xa1/0x1f0
[<ffffffff8080ad81>] netlink_sendmsg+0x1c1/0x3e0
[<ffffffff80799b8a>] sock_sendmsg+0x1a/0x30
[<ffffffff8079a376>] ___sys_sendmsg+0x1e6/0x200
[<ffffffff8079b404>] SyS_sendmsg+0x44/0x80
[<ffffffff802016d5>] do_syscall_64+0x75/0x2c0
[<ffffffff80c0008d>] entry_SYSCALL_64_after_hwframe+0x59/0xbe
[<ffffffffffffffff>] 0xffffffffffffffff
/var/log# cat /proc/15126/stack
[<ffffffff8080a819>] netlink_attachskb+0x189/0x1d0
[<ffffffff8080a991>] netlink_unicast+0xa1/0x1f0
[<ffffffff8080ad81>] netlink_sendmsg+0x1c1/0x3e0
[<ffffffff80799b8a>] sock_sendmsg+0x1a/0x30
[<ffffffff8079a376>] ___sys_sendmsg+0x1e6/0x200
[<ffffffff8079b404>] SyS_sendmsg+0x44/0x80
[<ffffffff802016d5>] do_syscall_64+0x75/0x2c0
[<ffffffff80c0008d>] entry_SYSCALL_64_after_hwframe+0x59/0xbe
[<ffffffffffffffff>] 0xffffffffffffffff
/var/log# cat /proc/2812/stack
[<ffffffff80255f6a>] do_wait+0x1aa/0x210
[<ffffffff802570f7>] kernel_wait4+0x97/0x120
[<ffffffff802571ef>] SyS_wait4+0x6f/0x80
[<ffffffff802016d5>] do_syscall_64+0x75/0x2c0
[<ffffffff80c0008d>] entry_SYSCALL_64_after_hwframe+0x59/0xbe
[<ffffffffffffffff>] 0xffffffffffffffff

可以发现 15126和15264进程都卡在了 netlink发送等待上。怀疑netlink socket收包队列有积压,导致发送端处于等待发送状态。

三、继续深挖

查看netlink相关信息

/var/log# cat /proc/net/netlink 
sk       Eth Pid    Groups   Rmem     Wmem     Dump     Locks     Drops     Inode
ffff88880b2cb000 0   2851   00000000 0        0        0 2        0        12002   
ffff888806d6e800 0   2707076566 00000000 0        0        0 2        0        12784   
ffff888806d6a000 0   3780   00000551 0        0        0 2        0        12810   
ffff88885a980000 0   0      00000000 0        0        0 2        0        3       
ffff88880a1b6000 0   2825818928 00000111 0        0        0 2        0        20919   
ffff888806d6d800 0   3498   00000111 0        0        0 2        0        12783   
ffff88880c210000 0   3410172620 00000000 0        0        0 2        0        12811   
ffff88880b2cb800 0   2855   00000001 0        0        0 2        0        11851   
ffff88880a5bf800 15  10000038 00000000 33557184 0        0 27       0        1652  --问题socket
//省略部分无关socket

发现socket ffff88880a5bf800 存在大量积压,基本确认是积压导致。

根据Eth 15 和Pid 10000038 ,对照代码发现是发送和接收告警信息的socket,负责接收处理的进程是warnd。

查看warnd进程栈

/var/log# ps | grep warnd2849 root     2325m S    /bin/warnd
22135 root     16448 S    grep warnd
/var/log# cat /proc/2849/stack
[<ffffffff802bfe03>] futex_wait_queue_me+0xc3/0x120
[<ffffffff802c01e2>] futex_wait+0x102/0x230
[<ffffffff802c275e>] do_futex+0x14e/0xc30
[<ffffffff802c32ab>] SyS_futex+0x6b/0x140
[<ffffffff802016d5>] do_syscall_64+0x75/0x2c0
[<ffffffff80c0008d>] entry_SYSCALL_64_a

发现warnd在等待futex 锁,是那个操作导致的呢,这就需要查看用户态的调用栈了。

四、再接再厉

查看warnd 用户栈

用gdb attach上warnd进程,查看当前栈

/var/log# gdb
GNU gdb (GDB) 11.2
Copyright (C) 2022 Free Software Foundation, Inc.
//省略无关部分
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) attach 2849
Attaching to process 2849
[New LWP 2945]
[New LWP 2946]
[New LWP 2947]
//省略无关部分
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
0x00007fcab97e4059 in ?? () from /lib/libc.so.6
(gdb) info threadId   Target Id                                 Frame 
* 1    Thread 0x7fcab8929800 (LWP 2849) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.62    Thread 0x7fcab8924640 (LWP 2945) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.63    Thread 0x7fcab8123640 (LWP 2946) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.64    Thread 0x7fcab7922640 (LWP 2947) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.6
//省略无关部分34   Thread 0x7fcaa802b640 (LWP 8217) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.635   Thread 0x7fcaa782a640 (LWP 8238) "warnd" 0x00007fcab9868add in sendmsg () from /lib/libc.so.636   Thread 0x7fcaa7029640 (LWP 8245) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.637   Thread 0x7fcaa611f640 (LWP 8260) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.638   Thread 0x7fcaa590d640 (LWP 8267) "warnd" 0x00007fcab97e4059 in ?? () from /lib/libc.so.639   Thread 0x7fcaa510c640 (LWP 8268) "warnd" 0x00007fcab9867196 in epoll_wait () from /lib/libc.so.6

除了线程35和39外,其他线程全部卡在相同的位置。

查看线程1,可以知道系统调用线程读写锁的写锁时因为得不到调度进入了休眠。那么这个锁被那个线程占有了呢?

(gdb) thread 1
[Switching to thread 1 (Thread 0x7fcab8929800 (LWP 2849))]
#0  0x00007fcab97e4059 in ?? () from /lib/libc.so.6
(gdb) bt full
#0  0x00007fcab97e4059 in ?? () from /lib/libc.so.6
No symbol table info available.
#1  0x00007fcab97ed4f1 in pthread_rwlock_wrlock () from /lib/libc.so.6
No symbol table info available.
#2  0x000000000040d5d3 in ?? ()
No symbol table info available.
#3  0x0000000000404ad9 in ?? ()
No symbol table info available.
#4  0x00007fcab978b1f7 in ?? () from /lib/libc.so.6
No symbol table info available.
#5  0x00007fcab978b2ac in __libc_start_main () from /lib/libc.so.6
No symbol table info available.
#6  0x0000000000404b01 in ?? ()
No symbol table info available.

我们再查看看35线程。通过查看代码发现,在sendmsg之前,线程已经持通过pthread_rwlock_wrlock 持有了写锁。也就是其他线程都在等待35线程释放写锁。那么35线程为什么不释放写锁呢?

  (gdb) thread 35
[Switching to thread 35 (Thread 0x7fcaa782a640 (LWP 8238))]
#0  0x00007fcab9868add in sendmsg () from /lib/libc.so.6
(gdb) bt full
#0  0x00007fcab9868add in sendmsg () from /lib/libc.so.6
No symbol table info available.
#1  0x00007fcab967f81d in fun_nl_sendto0 () from /lib/libfun_nl_ipc.so
No symbol table info available.
#2  0x00007fcab9b2a61a in send_warn () from /lib/libwarnapi.so
No symbol table info available.
#3  0x00000000004159d0 in ?? ()
No symbol table info available.
#4  0x0000000000415dbc in ?? ()
No symbol table info available.
#5  0x000000000040c9c5 in ?? ()
No symbol table info available.
#6  0x00007fcab9b62067 in ?? () from /lib/libevent.so
No symbol table info available.
#7  0x00007fcab9b62314 in ?? () from /lib/libevent.so
No symbol table info available.
#8  0x00007fcab9b62568 in ?? () from /lib/libevent.so
No symbol table info available.
#9  0x000000000040ca8e in ?? ()
No symbol table info available.
#10 0x00007fcab97e731a in ?? () from /lib/libc.so.6
No symbol table info available.
#11 0x00007fcab9866db0 in clone () from /lib/libc.so.6

查代码发现35线程sendmsg就是向 已经积压的netlink socket 发送warn消息。因为netlink socket积压,导致35线程进入休眠等待。

分析到这里,基本逻辑差不多通顺了。

  1. 压力测试导致netlink socket积压
  2. 35线程获取写锁后,向netlink socket发送消息。因为积压导致休眠。
  3. 其他线程包括netlink socket消息接受处理的线程因为获取不到写锁,导致休眠。
  4. 此时:线程35发送消息持有写锁,等待netlink socket buffer空闲。处理netlink socket消息的线程,等待写锁。–根因
  5. cli命令行进程会向warnd发送netlink消息,因为netlink socket消息积压(消息没有得到及时处理),导致发送进程进入等待休眠。

后记

warnd进程主要处理其他进程发来的warn消息,自己也发送warn消息。在锁的处理上不够完善,导致压力测试下,socket接收队列打满后,形成了死锁。

相关文章:

[deadlock]死锁导致的设备登录无响应问题

[deadlock]死锁导致的设备登录无响应问题 一、问题现象二、初步观察三、继续深挖查看netlink相关信息查看warnd进程栈 四、再接再厉查看warnd 用户栈 后记 一、问题现象 实验室一台压力测试设备突然无法登录&#xff0c;无论web页面&#xff0c;ssh或者telnet登录&#xff0c;…...

2024年10月21日计算机网络,乌蒙第一部分

【互联网数据传输原理 &#xff5c;OSI七层网络参考模型】 https://www.bilibili.com/video/BV1EU4y1v7ju/?share_sourcecopy_web&vd_source476fcb3b552dae37b7e82015a682a972 mac地址相当于是名字&#xff0c;ip地址相当于是住址&#xff0c;端口相当于是发送的东西拿什…...

ESlint代码规范

这里写目录标题 ESlint代码规范解决代码规范错误 ESlint代码规范 代码规范&#xff1a;一套写代码的约定规则。例如&#xff1a;“赋值符号左右是否需要空格” “一行代码结束是否要加分号” JavaScript Standard Style规范说明&#xff1a;https://standardjs.com/rules-zhc…...

【Vue.js设计与实现】第三篇第11章:渲染器-快速 Diff 算法-阅读笔记

文章目录 11.1 相同的前置元素和后置元素11.2 判断是否需要进行 DOM 移动操作11.3 如何移动元素11.4 总结 系列目录&#xff1a;【Vue.js设计与实现】阅读笔记目录 非常快的Diff算法。 11.1 相同的前置元素和后置元素 不同于简单 Diff 算法和双端 Diff 算法&#xff0c…...

材质变体 PSO学习笔记

学习笔记 参考各路知乎大佬文章 首先是对变体的基本认知 概括就是变体是指根据引擎中上层编写(UnityShaderLab/UE连连看)中的各种defines情况&#xff0c;根据不同平台编译成的底层shader&#xff0c;OpenGL-glsl/DX(9-11)-dxbc DX12-dxil/Vulkan-spirv&#xff0c;是打到游…...

2024年【烟花爆竹储存】考试及烟花爆竹储存复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 烟花爆竹储存考试参考答案及烟花爆竹储存考试试题解析是安全生产模拟考试一点通题库老师及烟花爆竹储存操作证已考过的学员汇总&#xff0c;相对有效帮助烟花爆竹储存复审模拟考试学员顺利通过考试。 1、【单选题】( …...

文件夹操作

文件夹操作 opendir closedir readdir write(fd,buf,strlen(buf)); return 0; } 作用 : 打开目录 opendir 所有头文件 : #include <sys/types.h> #include <dirent.h> 函数 : DIR *opendir(const char *name); 参数&#xff1a; name &#xff1a;目…...

如何制作一台自己想要的无人机?无人机改装调试技术详解

制作一台符合个人需求的无人机并对其进行改装调试&#xff0c;是一个既具挑战性又充满乐趣的过程。以下是从设计、选购材料、组装、调试到改装的详细步骤&#xff1a; 一、明确需求与设计 1. 明确用途与性能要求&#xff1a; 确定无人机的使用目的&#xff0c;如航拍、比赛、…...

Linux -- 进程间通信、初识匿名管道

目录 进程间通信 什么是进程间通信 进程间通信的一般规律 前言&#xff1a; 管道 代码预准备&#xff1a; 如何创建管道 -- pipe 函数 参数&#xff1a; 返回值&#xff1a; wait 函数 参数&#xff1a; 验证管道的运行&#xff1a; 源文件 test.c &#xff1a; m…...

网站的SSL证书快到期了怎么办?怎么续签?

网站的SSL证书即将到期时&#xff0c;需要续签一个新的证书以保持网站的安全性和信任度。以下是续签SSL证书的一般步骤&#xff1a; 1. 选择证书提供商 如果您之前使用的是免费证书&#xff0c;您可以选择继续使用同一提供商的免费证书服务进行续签。如果您需要更高级别的证书…...

解決爬蟲代理連接的方法

爬蟲在運行過程中常常會遇到代理連接的問題&#xff0c;這可能導致數據抓取的效率降低甚至失敗。 常見的代理連接問題 代理IP失效&#xff1a;這是最常見的問題之一。有些代理IP可能在使用一段時間後失效&#xff0c;導致連接失敗。 連接超時&#xff1a;由於網路不穩定或代…...

Prometheus 监控Harbor

你好&#xff01;今天分享的是基于Prometheus监控harbor服务。 在之前的文章中分别介绍了harbor基于离线安装的高可用汲取设计和部署。那么&#xff0c;如果我们的harbor服务主机或者harbor服务及组件出现异常&#xff0c;我们该如何快速处理呢&#xff1f; Harbor v2.2及以上…...

SQL 干货 | SQL 半连接

大多数数据库开发人员和管理员都熟悉标准的内、外、左和右连接类型。虽然可以使用 ANSI SQL 编写这些连接类型&#xff0c;但还有一些连接类型是基于关系代数运算符的&#xff0c;在 SQL 中没有语法表示。今天我们将学习一种这样的连接类型&#xff1a;半连接&#xff08;Semi …...

洛谷 P1226:【模板】快速幂

【题目来源】https://www.luogu.com.cn/problem/P1226【题目描述】 给你三个整数 a&#xff0c;b&#xff0c;p&#xff0c;求 a^b mod p。【输入格式】 输入只有一行三个整数&#xff0c;分别代表 a&#xff0c;b&#xff0c;p。【输出格式】 输出一行一个字符串 a^b mod ps&a…...

nginx常规操作

Linux下查找Nginx配置文件位置 1、查看Nginx进程 ps -aux | grep nginx 圈出的就是Nginx的二进制文件 2、测试Nginx配置文件 /usr/sbin/nginx -t 可以看到nginx配置文件位置 3、nginx的使用(启动、重启、关闭) 首先利用配置文件启动nginx。 nginx -c /usr/local/nginx/conf…...

Docker镜像不能访问

Get "https://registry-1.docker.io/v2/": dial tcp 192.168.10.194:443: connect: connection refused Idea推送镜像至Harbor私服&#xff0c;报以上错误&#xff0c;Docker镜像地址不能访问&#xff0c;更新Harbor服务器Docker镜像地址&#xff0c;重启Docker服务…...

TCP simultaneous open测试

源代码 /*************************************************************************> File Name: common.h> Author: hsz> Brief:> Created Time: 2024年10月23日 星期三 09时47分51秒**********************************************************************…...

Spring 配置文件动态读取pom.xml中的属性

需求&#xff1a; 配置文件中的 spring.profiles.active${env}需要打包时动态绑定。 一、方案&#xff1a; 在pom.xml文件中配置启用占位符替换 <profiles><!-- 本地开发 --><profile><id>dev</id><properties><env>dev</env>…...

Konva 组,层级

代码&#xff1a; <template><div class"rect"><div class"header"> <!-- <el-button type"primary" click"show">展示</el-button>--> <!-- <el-button type"success&quo…...

vue图片加载失败的图片

1.vue图片加载失败的图片 这个问题发生在测试环境和开发本地&#xff0c;线上环境是可以的&#xff0c;测试环境估计被第三方屏蔽了 2.图片有&#xff0c;却加载不出来 <template v-slot:imageUrlsSlots"{ row }"><div class"flexRow rowCenter"&…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。

2024 年&#xff0c;高端封装市场规模为 80 亿美元&#xff0c;预计到 2030 年将超过 280 亿美元&#xff0c;2024-2030 年复合年增长率为 23%。 细分到各个终端市场&#xff0c;最大的高端性能封装市场是“电信和基础设施”&#xff0c;2024 年该市场创造了超过 67% 的收入。…...