本周在开发调试视频会议标准网关的并发量及稳定性过程中,程序在不断的开会和退会过程中,偶现标准网关会出现崩溃的问题,通过gdb调试产生的core文件,查看core文件的堆栈信息,发现每次崩溃都是在PTimerList的线程回调函数Process中,PTimer的析构函数中,通过阅读PTimer相关的源码,在PTimerList线程的回调函数中会调用相应PTimer的超时处理函数以及PTimer的移除等操作,但是也没有发现什么不对的地方。网关在结束某次呼叫时,在释放PTimer前,会调用相应PTimer的Stop(true)函数,正常情况下Stop函数里面有一个信号量会等待从PTimerList的激活队列中安全移除再返回(是否等待,有一个条件就是判断调用Stop函数的线程是否就是PTimerList线程本身,如果是则不等待直接退出,如果不是则等待),但是发现程序还是在PTimer析构时崩溃了,最后通过日志打印发现PTimer Stop时没有等待直接退出了,结合网关代码,发现是在某一个PTimer A的超时函数中又去调用了其他PTimer的操作,如PTimer B的Stop操作,导致B并没有安全的从PTimerList的激活对列中移除,由于delete PTimer B的是线程thread1,调用PTimer B的超时函数的thread2,最终导致程序崩溃。
解决方法就是,在PTimer的超时函数中不要调用其他任何PTimer的操作。