live555堆栈溢出问题

最近使用Live555遇到一个堆栈溢出问题,各位可能也会遇到,写出来分享一下;

应用场景如下图所示:


Mediaserver是基于live555的一个流媒体服务器,负责解析platform送过来的码流,并建立RTSP服务;decoder向mediaserver发送RTSP请求,收到码流后再进行处理;

现在的情况是mediaserver有概率会出现堆栈溢出,通过日志分析,堆栈溢出时platform没有送码流,而decoder仍然不断向mediaserver发送RTSP请求根据崩溃dump中显示的堆栈调用层次,走读代码并画出程序处理流程图如下:


  乍一看这个流程图可能会有点晕,不捉急,先来回顾一下live555框架设计的基本思想;

1)  live555框架是单线程结构,所有任务都是单线程执行;

2)  live555所有任务都会在doEventLoop函数中执行;

3)  live555网络模型是select模型,有连接到来时会把相应的socket加入到select集合中;扫描处理完select中的socket之后,再进行tasklist处理,具体可以参考doEventLoop函数源码。

再了解一下RTSP请求的基本流程,一般来说就四个:

OPTION-------DESCRIBE---------SETUP----------PLAY

 

好了,关于本文,框架相关的了解上面这些就差不多了,下面看具体流程处理:

1)  正常没有请求时,doEventLoop循环;

2)  收到RTSP请求(这里具体指describe请求),live555需要从码流中解析出SDP信息,然后回送给请求方;

问题就在这里了,由于platform并没有送码流给mediaserver,所以live555就取不到码流进行解析,那么解析SDP信息的任务就卡住了

下面是一段解析SDP相关的代码:


无论解析SDP信息成功还是失败,都会调用doEventLoop函数,实际上就是在当前执行的loop1中新建了一个loop2; 分两种情况讨论:

a)        解析SDP成功

解析成功后fDoneFlag是有效的,loop2会直接跳转到break;语句,退出循环,getAuxSDPLine可以直接返回;

b)        解析SDP失败

解析失败,先来看检验解析结果的函数checkForAuxSDPLine


函数最后一行就是把checkForAuxSDPLine任务重新添加到tasklist中,此后会在loop2中调用tasklist,执行SDP信息检验任务;若SDP信息获取完成,loop2自然会退出,loop1中的getAuxSDPLine也可以直接返回;

但在某些情况下,如platform不送码流给mediaserverlive555是解析sdp的任务就会永远卡在loop2,无法进行下去; decoder发送RTSP请求后,迟迟收不到响应包,就会重发RTSP请求,而这个新的RTSP请求会被loop2接收,重新再走一遍DESCRIBE命令处理流程,由于还是获取不到SDP信息,所以会新建循环loop3,然后卡在loop3里面……….

loop1
{
   loop2
   {
	loop3
        {…}
   }
}

这样再对比上面的流程图的就很清楚了,decoder每发一个RTSP请求,就会多一层loop的嵌套,发个几百个请求堆栈自然就溢出了。

 

既然知道了问题原因,那么解决就比较简单了,只要能做到避免嵌套的方案都可以;这里提供一个简单的计数方案:

handleCmd_DESCRIBE函数中有一个mediasession的计数:

session->incrementReferenceCount();

只要做一个计数的限制,比如说count值大于10,就在subsession中调用setDoneFlag函数退出循环。

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值