freeswitch 1.10.10-dev录音早期媒体卡通道的bug分析
最近编译了fs 1.10.10-dev也就是 master版本(2023年7月6日) 给几个客户升级了一下,发现非常不稳定(每天都有几个通道卡在early状态),最近才有空来分析原因。
之前跑的是1.10.8 release 版本,从来没出现过这个问题,我把 1.10.8的代码和1.10.10-dev的代码整体对比了一下,整体改变不大,其中 switch_core_media_set_codec 函数的修改引擎我的警惕,因为这个修改时直接修改了互斥锁
switch_core_session_lock_codec_write(session);
switch_core_session_lock_codec_read(session);
的锁定范围。我查看了一下这个提交说明
2023年6月12日 这个提交给合并到到了master
SHA-1: 645b610e7968594910dd2368c511fbc93c1373b7
- Merge pull request #2109 from signalwire/switch_core_media_set_codec
[Core] Fix possible deadlock in switch_core_media_set_codec()
晚上 我联系客户 看看有没有卡在early状态的通道,刚好有一个,把所有线程的调用堆栈 输出来, 还真是卡在 switch_core_media_set_codec 。
#0 0x00007f9dc597a54d in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f9dc5975eb6 in _L_lock_941 () from /lib64/libpthread.so.0
#2 0x00007f9dc5975daf in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007f9dc8687759 in fspr_thread_mutex_lock (mutex=<optimized out>) at locks/unix/thread_mutex.c:92
#4 0x00007f9dc850e895 in switch_mutex_lock (lock=<optimized out>) at src/switch_apr.c:301
#5 0x00007f9db9c9029c in sofia_receive_message (session=0x7f9cf5b4a7c8, msg=0x7f9d345ac4d0) at mod_sofia.c:1526
#6 0x00007f9dc853f80b in switch_core_session_perform_receive_message (session=session@entry=0x7f9cf5b4a7c8, message=message@entry=0x7f9d345ac4d0, file=file@entry=0x7f9dc86a961d "src/switch_core_io.c", func=func@entry=0x7f9dc86a9970 <__func__.19414> "switch_core_session_read_frame", line=line@entry=416) at src/switch_core_session.c:930
#7 0x00007f9dc854aa7e in switch_core_session_read_frame (session=session@entry=0x7f9cf5b4a7c8, frame=frame@entry=0x7f9d345ae568, flags=flags@entry=0, stream_id=stream_id@entry=0) at src/switch_core_io.c:416
#8 0x00007f9dc8608251 in switch_ivr_sleep (session=0x7f9cf5b4a7c8, ms=100, sync=<optimized out>, args=0x0) at src/switch_ivr.c:294
#9 0x00007f9daeb4dcc5 in ?? () from /ddt/fs/mod/mod_cti.so
#10 0x00007f9dc8543b5b in switch_core_session_exec (session=0x7f9cf5b4a7c8, application_interface=application_interface@entry=0x19077a0, arg=arg@entry=0x7f9d345aeb40 "38981 2000") at src/switch_core_session.c:2964
#11 0x00007f9dc85441ef in switch_core_session_execute_application_get_flags (session=<optimized out>, app=0x7f9db140b89b "cti_wait_for_answer", arg=0x7f9d345aeb40 "38981 2000", flags=<optimized out>) at src/switch_core_session.c:2824
#12 0x00007f9daeb8eb7e in ?? () from /ddt/fs/mod/mod_cti.so
#13 0x00007f9daeb92619 in ?? () from /ddt/fs/mod/mod_cti.so
#14 0x00007f9dc853c9c5 in switch_core_session_thread_pool_worker (thread=0x7f9d45af47a0, obj=<optimized out>) at src/switch_core_session.c:1790
#15 0x00007f9dc868d760 in dummy_worker (opaque=0x7f9d45af47a0) at threadproc/unix/thread.c:151
#16 0x00007f9dc5973ea5 in start_thread () from /lib64/libpthread.so.0
#17 0x00007f9dc4fc7b0d in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7f9d2f76b700 (LWP 30595)):#0 0x00007f9dc597a54d in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007f9dc5975eb6 in _L_lock_941 () from /lib64/libpthread.so.0
#2 0x00007f9dc5975daf in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007f9dc8687759 in fspr_thread_mutex_lock (mutex=<optimized out>) at locks/unix/thread_mutex.c:92
#4 0x00007f9dc850e895 in switch_mutex_lock (lock=<optimized out>) at src/switch_apr.c:301
#5 0x00007f9dc852c6ec in switch_core_session_lock_codec_read (session=<optimized out>) at src/switch_core_codec.c:74
#6 0x00007f9dc8561e7c in switch_core_media_set_codec (session=session@entry=0x7f9cf5b4a7c8, force=force@entry=0, codec_flags=0) at src/switch_core_media.c:3608
#7 0x00007f9dc856763e in switch_core_media_activate_rtp (session=0x7f9cf5b4a7c8) at src/switch_core_media.c:8565
#8 0x00007f9db9cf73de in sofia_media_activate_rtp (tech_pvt=tech_pvt@entry=0x7f9cf5b53ff8) at sofia_media.c:58
#9 0x00007f9db9cf745e in sofia_media_tech_media (tech_pvt=tech_pvt@entry=0x7f9cf5b53ff8, r_sdp=<optimized out>, type=type@entry=SDP_TYPE_REQUEST) at sofia_media.c:189
#10 0x00007f9db9ccab5a in sofia_handle_sip_i_state (de=0x7f9d983bcea0, tags=0x7f9d882ae950, sip=0x0, sofia_private=<optimized out>, nh=0x7f9da1db69b0, profile=0x1ac35070, nua=0x7f9d98040be0, phrase=0x7f9d882aece6 "Ringing", status=183, session=0x7f9cf5b4a7c8) at sofia.c:7683
#11 our_sofia_event_callback (event=nua_i_state, status=<optimized out>, phrase=0x7f9d882aece6 "Ringing", nua=0x7f9d98040be0, profile=0x1ac35070, nh=0x7f9da1db69b0, sofia_private=0x7f9d1927a640, sip=0x0, de=de@entry=0x7f9d983bcea0, tags=0x7f9d882ae950) at sofia.c:1813
#12 0x00007f9db9ccea5b in sofia_process_dispatch_event (dep=0x7f9d2f76a2c0) at sofia.c:2253
#13 0x00007f9db9c8ffc9 in sofia_receive_message (session=0x7f9cf5b4a7c8, msg=0x7f9d2f76aa20) at mod_sofia.c:1347
#14 0x00007f9dc853f6d5 in switch_core_session_perform_receive_message (session=session@entry=0x7f9cf5b4a7c8, message=message@entry=0x7f9d2f76aa20, file=file@entry=0x7f9dc86c5e35 "src/switch_ivr.c", func=func@entry=0x7f9dc86c6ed0 <__func__.19070> "switch_ivr_parse_signal_data", line=line@entry=893) at src/switch_core_session.c:853
#15 0x00007f9dc8604f9c in switch_ivr_parse_signal_data (session=session@entry=0x7f9cf5b4a7c8, all=all@entry=SWITCH_TRUE, only_session_thread=only_session_thread@entry=SWITCH_FALSE) at src/switch_ivr.c:893
#16 0x00007f9dc8604fec in switch_ivr_parse_all_signal_data (session=session@entry=0x7f9cf5b4a7c8) at src/switch_ivr.c:906
#17 0x00007f9dc8605007 in switch_ivr_parse_all_messages (session=session@entry=0x7f9cf5b4a7c8) at src/switch_ivr.c:852
#18 0x00007f9dc8607b4a in switch_ivr_parse_all_events (session=session@entry=0x7f9cf5b4a7c8) at src/switch_ivr.c:925
#19 0x00007f9dc8548632 in switch_core_session_run (session=0x7f9cf5b4a7c8) at src/switch_core_state_machine.c:710
#20 0x00007f9dc85412ae in switch_core_session_thread (thread=<optimized out>, obj=0x7f9cf5b4a7c8) at src/switch_core_session.c:1726
#21 0x00007f9dc853c9c5 in switch_core_session_thread_pool_worker (thread=0x7f9d38410920, obj=<optimized out>) at src/switch_core_session.c:1790
#22 0x00007f9dc868d760 in dummy_worker (opaque=0x7f9d38410920) at threadproc/unix/thread.c:151
#23 0x00007f9dc5973ea5 in start_thread () from /lib64/libpthread.so.0
#24 0x00007f9dc4fc7b0d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f9dc8db78c0 (LWP 11507)):
接下来就是分析代码找出死锁原因了
Thread 2 (Thread 0x7f9d2f76b700 (LWP 30595)): 和线程 Thread 1 (Thread 0x7f9dc8db78c0 (LWP 11507)): 调用堆栈都有 sofia_receive_message 这个函数
具体代码
switch_mutex_lock(tech_pvt->sofia_mutex);if (switch_core_session_in_thread(session)) {de->session = session;}sofia_process_dispatch_event(&de);switch_mutex_unlock(tech_pvt->sofia_mutex);
Thread 2 (Thread 0x7f9d2f76b700 (LWP 30595)): 卡在 switch_mutex_lock(tech_pvt->sofia_mutex);了
Thread 1 (Thread 0x7f9d2f76b700 (LWP 30595)) 成功获取了 tech_pvt->sofia_mutex) 锁定进入了sofia_process_dispatch_event。最后卡在switch_core_media_set_codec函数里面的switch_core_session_lock_codec_write(session)步骤。
通过看
Thread 2 (Thread 0x7f9d2f76b700 (LWP 30595)): 的调用堆栈 函数 switch_core_session_read_frame 里面调用了switch_core_session_perform_receive_message,
对应代码
switch_mutex_lock(session->codec_read_mutex);...省略很多代码if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {switch_core_session_message_t msg = { 0 };msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;switch_core_session_receive_message(session, &msg);switch_set_flag(session, SSF_WARN_TRANSCODE);}
switch_mutex_lock(session->codec_read_mutex); 这个锁定和 switch_core_session_lock_codec_write(session) 对应的是一个锁定,至此 这个死锁的bug,我们就分析出来了。
Merge pull request #2109 from signalwire/switch_core_media_set_codec 这个提交为了解决一个bug,导致了一个更深的bug。
触发的原因是 cti模块有处理早期媒体,如果外呼用的是 ignore_early_media=true 应该是不会触发这个的bug的。
解决这个bug的方法是 调用 switch_core_session_receive_message 之前先 解锁 switch_mutex_unlock(session->codec_read_mutex)。代码如下。
msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;switch_mutex_unlock(session->codec_read_mutex);switch_core_session_receive_message(session, &msg);switch_mutex_lock(session->codec_read_mutex);switch_set_flag(session, SSF_WARN_TRANSCODE);
相关文章:
freeswitch 1.10.10-dev录音早期媒体卡通道的bug分析
最近编译了fs 1.10.10-dev也就是 master版本(2023年7月6日) 给几个客户升级了一下,发现非常不稳定(每天都有几个通道卡在early状态),最近才有空来分析原因。 之前跑的是1.10.8 release 版本,从来没出现过这个问题&…...
Zebec Protocol ,不止于 Web3 世界的 “Paypal”
Paypal 是传统支付领域的巨头企业,在北美支付市场占有率约为 77% 以上。从具体的业务数据看,在8月初,Paypal 公布的 2023 年第二季度财报显示,PayPal 第二季度净营收为 73 亿美元,净利润为 10.29 亿美元。虽然 Paypal …...
Gcd 2023牛客暑期多校训练营6 G
登录—专业IT笔试面试备考平台_牛客网 题目大意:给出一个集合,集合中初始有2个数x,y(x!y),每次操作可以将集合中任意两个不等的数的差放入集合或者将两个不等的数的gcd放入集合,给出一个数z,问z有没有可能出现在集合里…...
常用C++编译器推荐
本文将为大家带来的是几款简单实用的C编译器(非IDE),希望大家喜欢。 GCC(GNU Compiler Collection) 官方网站: GCC, the GNU Compiler Collection- GNU Project GCC有Windows移植版本,比较出名的就是Min…...
C++QT教程1——QT概述(下载与安装)
文章目录 1 Qt概述1.1 什么是Qt1.2 Qt的发展史1.3 Qt版本1.4 Qt的下载与安装下载地址:其实我是有点懵逼的,因为还有个qtcreator,我差点不知道下哪个。。。(qt框架比qtcreator功能更多更强大) 安装 1.5 Qt的优点1.6 QT成…...
在oracle SQL中创建返回表的函数
这是我的职责 create or replace FUNCTION split(i_str IN VARCHAR2,i_delim IN VARCHAR2 DEFAULT : ) RETURN TABLE AS BEGINRETURN SELECT trim(regexp_substr(i_str, [^||i_delim||], 1, LEVEL)) str FROM projetCONNECT BY instr(i_str, i_delim, 1, LEVEL - 1) …...
Kubernetes API Aggregation API聚合
Kubernetes API Aggregation - Kubernetes - Wiki.Shileizcc.com API 聚合机制是 Kubernetes 1.7 版本引入的特性,能够将用户扩展的 API 注册到 kube-apiserver 上,仍然通过 API Server 的 HTTP URL 对新的 API 进行访问和操作。为了实现这个机制&#…...
【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台
吃完快餐粥,除了粥的味道不错之外,我对个快餐盒的圆盖子产生了兴趣,能否做个极低成本的简易机器人呢?也许只需要二十元左右 知识点:轮子(wheel) 中国词语。是用不同材料制成的圆形滚动物体。简…...
重生学c++系列第三课类和对象(上)
好的我们重生c系列的前两期已经介绍完了c祖师爷针对C语言补充的几个新功能,现在我们进入c的真正课题学习——类与对象: C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 比如说我们洗菜做饭&am…...
驱动开发-按键中断
编写LED灯的驱动,使用GPIO子系统,里面添加按键的中断处理 1.应用程序发送指令控制LED亮灭 2.按键1 按下,led1电位反转 按键2按下,led2电位反转 按键3 按下,led3电位反转 功能函数 #include<stdlib.h> #inclu…...
数据结构 | 二叉树的应用
目录 一、解析树 二、树的遍历 一、解析树 我们可以用解析树来表示现实世界中像句子或数学表达式这样的构造。 我们可以将((73)*(5-2))这样的数学表达式表示成解析树。这是完全括号表达式,乘法的优先级高于加法和减法,但因为有括号,所以在…...
python:卡尔曼和贝叶斯滤波器
本文分享一个Filerpy的说明文档和代码示例文档,有关于 Python 中的卡尔曼和贝叶斯滤波器。该方法可以应用于气象遥感等领域。 说明文档:https://filterpy.readthedocs.io/en/latest/kalman/KalmanFilter.html 参考代码链接:https://nbviewer.…...
走进 Go 语言基础语法 | 青训营 (1)
Powered by:NEFU AB-IN 文章目录 走进 Go 语言基础语法 | 青训营 (1)代码注释代码模板 走进 Go 语言基础语法 | 青训营 (1) 代码注释 /** Author: NEFU AB-IN* Date: 2023-08-06 09:44:15* FilePath: \GoTest\a.go* LastEditTime: 2023-08-06 11:00:45*/ package mainimport (&…...
基于边缘无线协同感知的低功耗物联网LPIOT技术:赋能智慧园区方案以及数字工厂领域
回到2000年左右,物联网的底层技术支撑还是“ZigBee”,虽然当时ZigBee的终端功耗指标其实也并不庞大,但是,“拓扑复杂导致工程实施难度大”、“网络规模小导致的整体效率低下”都成为限制其发展的主要因素。 LPWAN,新一…...
【《快速构建AI应用——AWS无服务器AI应用实战》——基于云的解决方案快速完成人工智能项目的指南】
基于云的人工智能服务可以自动完成客户服务、数据分析和财务报告等领域的各种劳动密集型任务。其秘诀在于运用预先构建的工具,例如用于图像分析的Amazon Rekognition或用于自然语言处理的AWS Comprehend。这样,就无须创建昂贵的定制软件系统。 《快速构…...
vue运行在IE浏览器空白报错SCRIPT1006: 缺少‘)‘ -【vue兼容IE篇】
其他浏览器均正常,但是切换ie模式,打开空白,F12打开报错缺少‘)‘ ,如下图 在搜狗浏览器下点开报错:定格在crypto-js处 解决: 步骤一:使用npm安装babel-polyfill 依赖(已安装了可忽…...
接口自动化测试Mock Get和Post请求
Mock可以模拟一个http接口的后台响应,可以模拟request,response 下载 moco-runner-0.11.0-standalone.jar 下载链接: https://pan.baidu.com/s/1bmFzvJPRnDlQ-cmuJ_3iRg 提取码: kpjv 确保安装了jdk,cmd下可以运行java -version 一、模拟不带参的get请求…...
WPF上位机8——C#与MySQL
ADO.NET 数据库连接 数据插入、删除、更改 数据查询 带单个参数 带多个参数 using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Wp…...
[JAVAee]网络编程-套接字Socket
目录 基本概念 发送端与接收端 请求与响应 编辑客户端与服务器 Socket套接字 分类 数据报套接字 流套接字传输模型 UDP数据报套接字编程 DatagramSocket API DatagramPacket API InetSocketAddress API 示例一: 示例二: TCP流数据报套接字编程 ServerSock…...
批量导出pdf为zip文件(可以修改zip中pdf名称)
核心代码 public static void compressZip1(HashMap<String,File> map, String rootPath, String zipFileName) throws FileNotFoundException {FileOutputStream fileOutputStream new FileOutputStream(zipFileName);ZipOutputStream zipOutputStream new ZipOutputS…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...
生信服务器 | 做生信为什么推荐使用Linux服务器?
原文链接:生信服务器 | 做生信为什么推荐使用Linux服务器? 一、 做生信为什么推荐使用服务器? 大家好,我是小杜。在做生信分析的同学,或是将接触学习生信分析的同学,<font style"color:rgb(53, 1…...
