close

我一生中, 遇過許多難纏的bug, 但沒有一個像這次碰到的, 那麼令人感到絕望 ... 由於我自幼就沒有接受極為嚴格的debug訓練, 因此差點就被擊倒 ... 所以要來紀錄這次的血淚歷史 XD

 

一開始是送測期間, 發現跑了一個晚上的 autopan, ptz就不動了, 也收不到圖 ...

 

先簡化環境, 於是我將機器和 camera 對接, 跑了一個晚上, 發現有機器重開、module reload、或ptz不會動的現象.

而在這些現象之前, 會有 CPU 100% 情況.

 

由於現象太過分散, 所以要一個個切開來看.

首先要釐清是系統還是module問題, 於是測試module什麼事都不做 ...

...... 沒事 ...

 

隨後測試拿掉 ONVIF, 也沒事.

 

這段時間, 做了一些沒意義又有點重複的實驗,

導致時間浪費不少, 這是我還要學習進步的地方.

總之, 最後把焦點鎖定在 onvif 內部的 soap api.

 

在多次實驗的過程中,

漸漸歸納出會造成 cpu loading 100% 的 prerequisite.

就是 memory leak !!!

於是, 接下來實驗的時間就能縮短,

只要有 memory leak 就代表問題還在,

不會像一開始那幾天, 總是要擺到系統出問題才能確認,

而這往往就耗掉了一整天的時間 ... 

 

由於 debug 花的時間太長, 終於引起上層關切 XD

我主管也跳進來幫我指點方向,

一個關鍵字 - Valgrind, 開啟了一扇窗 !!!

 

為了簡化環境, 我寫了一個小執行檔,

只做 load module 跟 invoke function.

此外, 也給 module 新增了 interface function.

再搭配 gdb 檢查實驗過程中不時發生的 segmentation fault

當環境終於能正常進行模擬,

最後就是 Valgrind 的使用了 !

 

Valgrind 追執行檔的 memory usage, 直接下 command 即可.

但我這次是要追進 shared object 裡頭,

執行檔內就不能下 dlclose, 否則 Valgrind 會無法判斷裡面的 function ...

當 shared object 內的 function 清楚的印出來,

正好印證了我之前的猜測 - 問題出在 ONVIF/SOAP 內部.

 

gsoap build 出來的 soap api 或 wsse 相關函式,

裡面都會有 memory allocation.

若是用 C++ 還可以藉由 destructor 去 release 這些 memory,

但 C 就不行了,

解法就在每一個 soap api 之後,

再去呼叫 soap_destroy、soap_end、soap_done.

Valgrind 顯示, 當我使用了這三個 function 以後,

所有 malloc/calloc 都會對應到 free, 

完成 !!!

 

雖然已經修到讓 Valgrind 秀不出 memory 存取問題,

但當我把 code 放在 embeded 上面跑,

寫一個定時印出 memory usage 的 shell script 來看,

還是有輕微的 memory leak 問題,

不過這應該跟我無關了 ....... 吧 XD

 

 

Reference:

dynamically load shared object & command line

http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html#DL-LIBRARY-EXAMPLE

 

使用 Valgrind

http://www.cprogramming.com/debugging/valgrind.html

 

Valgrind 與 memory leak 有關的敘述:

http://valgrind.org/docs/manual/faq.html#faq.deflost

 

程式結束以前, 拿掉 dlclose, 否則 Valgrind 追不進 shared object 的 function

http://valgrind.org/docs/manual/faq.html#faq.unhelpful

 

 

arrow
arrow
    全站熱搜

    kk 發表在 痞客邦 留言(0) 人氣()