HI3559A系統卡死問題-修復

結論:

1 rtsp_client綁定了cpu3核心,cpu3被佔滿了,導致vdec線程輪到cpu3執行的時間會變長,導致vdec_get方法不及時,導致vdec緩衝區滿了,導致vdec_send失敗,導致vdec的vb視頻幀vpss增加,如果打開IA,那麼VB就不夠用了。
2 卡頓的原因,我認爲是vdec線程獲取視頻流時,會調用linux中斷或系統調用,當跑到cpu3時,就會變得異常卡頓,返回很慢或不返回,進而導致任何與此進程有關的其他進程也卡頓,比如ps、top等命令
3 嘗試解決,設想可以通過把vdec線程綁核心cpu2解決,失敗,get_frame仍然有很慢的情況,我估計海思底層的進程在cpu3執行的時候卡住了。
4 徹底解決,問題確定是由於recvfrom失敗後的無限循環導致的,在曉熙的幫助下,在live555中找到了釋放接口,在recvfrom失敗時候調用此接口。

排查比較麻煩,具體如下:

1 第一次問題發生在2020.01.17,當時的rtsp_client用的是老版本,丟幀嚴重。

(1)內存泄漏,由於系統卡死,ia結果出的非常慢,通常幾秒一次,視頻緩存的datacenter不斷增大,其實不是泄漏,應該是把緩存喫沒了
(2)卡死原因,當時因爲設備重啓,可分析資源不多,從log分析,確實rtsp_client丟了很多幀,所以判斷,可能是一些異常幀把海思底層搞掛了,導致系統卡死
(3)海思內存不足,我創建了一個導致海思還存不夠的環境,從log來看跟問題設備完全不一樣,系統也不卡死,所以當時我就排除了海思的內存不足,我認爲是問題(2)的卡死導致海思底層出故障了,
(4)當時的結論,rtsp_client丟幀驗證導致海思底層崩潰,更新了rtsp_client繼續驗證。由於出問題的設備帶狗,設備重啓了, 留下的可分析資源有限,而且也不能復現,所以只能暫時這樣判斷,等待復現。

2 2020.02.15,問題復現。

(1)分析日誌和當時的日誌如出一轍,證明是相同問題。
(2)本次設備不帶狗,設備未重啓。
(3)經過排查,發現前端相機出流異常卡頓,有時候1S一幀,有時候幾秒一幀,系統在不斷的重連和等待,我懷疑是這個過程導致了異常。
(4)把配置文件考出,在我自己設備上跑,果然,又出了,問題源頭找到。
(5)但是不管它怎樣卡,設備不應該掛纔對,繼續排查,通過日誌,我發現我們的幀率監控timer不斷的往海思底層設置幀率信息,logmpp有src<dst幀率的錯誤日誌,我懷疑是這個把海思搞掛了。
注掉此timer,果然沒有這個日誌了,不過跑了一會,又出了。但是程序還是要加上src<dst幀率的判斷。
(6)ia的send、detect、posequality、filter等模塊打印幀數信息,看不出異常。
(7)hw_vdec的busy_count打印出來,也是正常,感覺是ia的視頻幀,並沒有泄露,查看vb,我發現一個現象,就是resize以後的幀並沒有泄露,原圖泄露了,由於兩個幀的釋放地方相同,再加上前面的打印,
我判定ia模塊並沒有泄漏內存幀,那到底是哪裏泄漏了海思底層的內存,百思不得其解。
(8)繼續排查vb,我發現ia使用的視頻幀的所有者是user,而還有一些視頻幀的所有者是vpss,問題會不會是出在了這個vpss。找到老化正常的設備,果然所有者是vpss的視頻幀爲0或者爲個數,不過刷幾下就沒了。
查看代碼,沒有其他使用vpss的模塊,我們用的視頻幀只有user,那爲什麼會vpss泄漏視頻幀?
(9)梳理下整個流程,視頻是vdec->vpss->user,如果沒有其他模塊使用vpss,那麼就是這個環節的vpss泄漏了,但是是綁定的爲什麼會泄漏,這時候我做了一個大膽的假設,因爲前端的視頻源非常差每秒<1幀,會不會vdec→vpss後,vpss做了緩存,由於幀不連續,vpss判斷此幀不完整,而自己緩存了。下一步驗證此假設。
(10)只跑1路視頻,打印出vdec_send幀的幀序號和總數,打印出user_get的幀序號和總數。對於單路的情況,vpss並沒有緩存的現象,所以我懷疑是不是某一路視頻異常,經過排查,發現,是異常視頻和正常視頻同時存在的時候有這個現象。
但是中午喫過飯後,又出現個奇怪的現象,我中午跑了3路異常視頻,1路正常視頻,經過一箇中午,系統則卡死了,但是這個問題跟16路時候不同,因爲VB還有164個剩餘,也就是VB還有剩餘的時候,系統依然會卡死,我懷疑,問題是正常路的視頻,長時間沒取一直往通道里面發送導致的。
(11)修改了兩處,VDEC線程加打印,且視頻幀獲取後不送IA,直接釋放。發現,系統依然會卡頓、卡死,這個時候vb內存還有剩餘,但是前面說的VPSS佔用的VB依然很高,說明,系統卡死不是VB不夠了導致的。那卡死是不是因爲vdec_send失敗了導致?
(12)vpss_get的線程注掉,這樣vdec_send一會就會返回失敗,觀察了很久,沒有發現卡頓問題,但是我發現一個現象,就是rtsp_client線程把cpu3給佔滿了。
(13)排查爲什麼rtsp_client把cpu3佔滿了,把vdec_send注掉,發現問題依然存在,繼續修改代碼,把16路視頻變成1路,問題依然存在,故此,問題定位。

小結:

解決過程一波三折,一開始定位的是rtsp_client,復現後調試信息增多,覺得不是,是ia的問題,再接着排查vdec,花費了大量時間,依然沒有找到根源。不過功夫不負有心人,終於從蛛絲馬跡中,最終又定位到rtsp_client把cpu3佔滿了。
(14)接下來就是分析live555,由於以前沒怎麼看過源碼,分析起來也是比較慢,多虧曉熙提示,使用在windows端加斷點的方式分析,加快了速度,下面是我對rtsp和live555的一些總結:
在這裏插入圖片描述
問題就出在了紅色環節,出現了死循環調用recvfrom。過程是這樣的,網絡環境較差,我們從DS相機中拉的視頻流出現了問題,流斷了,而且相機使用了linger選項,這就導致我們的select異常了,進而導致recv認爲一直有數據,但是由於連接斷了,也收不出來數據,繼續返回錯誤,無限循環,耗滿了一個cpu核。而對於沒有linger選項的視頻流,我試了下,不會進入此異常。下面的優化可以解決此問題。一開始我擔心外部釋放改爲內部釋放後會不會導致泄漏,或者有其他影響,從代碼分析來看,不會重複釋放,理論上沒有影響,後續進行老化驗證。
在這裏插入圖片描述
(15)老化再次出問題,定位發現是DS相機的流異常斷開後,我們重連成功,有小概率視頻通道0的視頻流發送到了信令通道1中,再次造成不收流的死循環,這個問題我暫時不想規避,不是這邊的問題,先看DS那邊的處理結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章