MS版本升级后,第三天,现场的同事告诉我,MS仍然有重启现象。
我于是在现场开启了ulimit -c unlimited。等待第二次重启后产生的core文件,拿到core文件后,发现进程重启发生在会议模式。而我们MS本次采用了的是桥接模式,应该不会用到会议模式。
我的直觉及多年的编程经验告诉,一旦程序走了不该走的分支,很有可能发生了内存越界赋值,导致该附近的变量的值被越界修改。
我显示修改了内存池的部分代码,将潜在有导致内存错误赋值的地方修改了。版本升级后,结果仍然重启。
于是思路一度闭塞,产品经理告诉我,一旦18号之前解决不了该问题,就需要我们的媒体服务器下线。该采购国外一款媒体服务器,那么就给别人做了嫁衣。
内心一度很煎熬,也有些无助,但我知道肯定是个BUG惹的祸。它就藏在代码里等着我去发现。
我于是静下心来,查看该变量附近和内存赋值相关的变量。逐渐我发现与RTP接收及转码的BUFFER。该BUFFER在使用FFMPEG进行转码时,对于转码后的BUFFER进行copy时,没有进行内存保护。
memcpy( out, m_pEnPkt.data, outsize );
没有对于outsize进行判断,于是我对该处代码做了大小的保护。int ret = fetch( &m_pEnPkt );
if ( ret >= 0 && m_pEnPkt.size > 0 ) { int outsize = m_pEnPkt.size; if(outsize>MAXAUDIOBUFFERSIZE) { LOG(ERROR,"TEncoder::fetch outsize too long %d",outsize); outsize=MAXAUDIOBUFFERSIZE; } memcpy( out, m_pEnPkt.data, outsize ); av_free_packet(&m_pEnPkt); return outsize; }
版本修改后,上线试运行。我静静等待too long的日志,结果这个too long的日志如期而至。于是我知道了,MS的这个最后的虫子被我抓住了。
目前MS在稳定的运行,潜在为公司节省了百万的成本。