AliOS Things 维测典型案例分析 —— 内存泄漏
維測(cè)典型案例分析1 —— 內(nèi)存泄漏
在系統(tǒng)運(yùn)行的過(guò)程中,內(nèi)存泄漏是較為常見(jiàn)但是很難復(fù)現(xiàn)的現(xiàn)象,一般的內(nèi)存泄漏點(diǎn)都是比較隱蔽的,每次幾十個(gè)字節(jié)的泄漏,往往需要壓測(cè)很久才能復(fù)現(xiàn)問(wèn)題。本節(jié)案例分析,我們從一個(gè)已經(jīng)壓測(cè)出來(lái)的問(wèn)題出發(fā),通過(guò)維測(cè)工具的使用,來(lái)看一次內(nèi)存泄漏的分析。
1. 問(wèn)題現(xiàn)象:
xx平臺(tái)壓測(cè)反復(fù)斷AP電源第488次連接通道時(shí)出現(xiàn)dump機(jī)現(xiàn)象
**
2. 重現(xiàn)步驟:?
b. .待連接穩(wěn)定后,斷開網(wǎng)絡(luò)(斷AP電源)
c? .5分鐘后恢復(fù)AP電源
d .查看設(shè)備端日志判斷設(shè)備是否上線
3. 問(wèn)題初步分析
從壓測(cè)過(guò)程看,是設(shè)備和路由器循環(huán)斷開重連的操作,沒(méi)有連云,也沒(méi)有起業(yè)務(wù)。這部分僅僅是調(diào)用廠商的wifi 驅(qū)動(dòng)庫(kù)。
從問(wèn)題出現(xiàn)的log來(lái)看,發(fā)生了系統(tǒng)crash,并且出現(xiàn)了典型了內(nèi)存不足的打印,如下:
(這個(gè)Log是我們維測(cè)體系中的設(shè)備端能力之一,將發(fā)生內(nèi)存出錯(cuò)時(shí)候的內(nèi)存使用情況全部輸出,方便定位)
這是由于內(nèi)存不足,無(wú)法從系統(tǒng)內(nèi)存池中mallo出動(dòng)態(tài)內(nèi)存,出現(xiàn)這種現(xiàn)象一般有2種原因:
初步分析到此,我們先用PC端維測(cè)工具對(duì)這個(gè)設(shè)備端log解析一把,看看有什么有價(jià)值的信息出現(xiàn)。維測(cè)工具的使用參加另一篇文章介紹。這里直接使用
python core_dump.py log xx.elf維測(cè)工具輸出了對(duì)設(shè)備端log的解析,打印出了上圖中內(nèi)存泄漏時(shí)的系統(tǒng)內(nèi)存使用情況的一次統(tǒng)計(jì),如下圖:
這里對(duì)系統(tǒng)crash時(shí)所有動(dòng)態(tài)內(nèi)存分配情況進(jìn)行了統(tǒng)計(jì),按照內(nèi)存分配size 從小到大的順序進(jìn)行了排列,每一行都包含著內(nèi)存malloc出來(lái)的地址,誰(shuí)申請(qǐng)了內(nèi)存,申請(qǐng)的次數(shù),申請(qǐng)的size大小,申請(qǐng)者在代碼中的位置等,一目了然。
我們一下就從圖中的最后一行(也就是占據(jù)系統(tǒng)內(nèi)存最多的組件)發(fā)現(xiàn)了異常點(diǎn):此時(shí)系統(tǒng)中還存在著982個(gè)timer,占據(jù)著70K+ 的系統(tǒng)內(nèi)存,這個(gè)肯定是有問(wèn)題的!
4.? 快速問(wèn)題復(fù)現(xiàn)
快速?gòu)?fù)現(xiàn)問(wèn)題是bug定位過(guò)程中非常重要的的一步。
由于壓測(cè)過(guò)程是每5分鐘斷開路由器,時(shí)間較長(zhǎng),我們嘗試重現(xiàn)構(gòu)造測(cè)試用例來(lái)復(fù)現(xiàn)這一現(xiàn)象。由前面分析可知,這一壓測(cè)過(guò)程只跟廠商wifi 驅(qū)動(dòng)有關(guān)。我們找到了2個(gè)通用接口來(lái)模擬這一過(guò)程:
?hal_wifi_suspend_station? ?---- 斷開路由器操作,會(huì)調(diào)用廠商底層的wifi disconnect
?netmgr_reconnect_wifi? ? ? ---- 連接路由器操作,會(huì)調(diào)用廠商底層的wifi connect
我們構(gòu)建的測(cè)試case代碼如下:
while (1) {krhino_mm_overview(NULL); /*重點(diǎn)關(guān)注這一行*/aos_msleep(5000);hal_wifi_suspend_station(NULL);netmgr_reconnect_wifi();}即:在系統(tǒng)上電啟動(dòng)必要的網(wǎng)絡(luò)初始化后,開始以5s為周期循環(huán)壓測(cè) suspend 和 reconnect
請(qǐng)注意while循環(huán)里的第一行:
krhino_mm_overview(NULL);這個(gè)接口是維測(cè)對(duì)外API 調(diào)試接口之一,會(huì)打印堆的相關(guān)統(tǒng)計(jì)。
維測(cè)調(diào)試API接口是debug的時(shí)候的重要手段之一,加上這些接口出版本,往往可以快速定位問(wèn)題
詳見(jiàn)?https://yuque.antfin-inc.com/aliosthings/mr5i1t/wupvbn#994230b2
這個(gè)接口打印如下所示(舉例):
========== Heap Info ========== ----------------------------------------------------------- [HEAP]| TotalSz | FreeSz | UsedSz | MinFreeSz || 0x0004A838 | 0x00047E50 | 0x000029E8 | 0x00047E50 | ----------------------------------------------------------- [POOL]| PoolSz | FreeSz | UsedSz | BlkSz || 0x00002000 | 0x00001E00 | 0x00000200 | 0x00000020 | -----------------------------------------------------------上面統(tǒng)計(jì)分成兩部分,HEAP與POOL。HEAP是總的統(tǒng)計(jì),POOL是HEAP的一部分。
HEAP與POOL的區(qū)別是,當(dāng)用戶使用
aos_malloc(size)來(lái)分配內(nèi)存的時(shí)候,size若小于32字節(jié)(由RHINO_CONFIG_MM_BLK_SIZE宏指定,在k_config.h中定義),malloc會(huì)在POOL上固定分配32字節(jié)內(nèi)存,反之則在HEAP上分配用戶定義size的內(nèi)存。
HEAP中的內(nèi)容含義:
- TotalSz,堆的總大小。
- FreeSz,當(dāng)前堆的空閑大小。
- UsedSz,當(dāng)前堆的使用量,即UsedSz = TotalSz – FreeSz。
- MinFreeSz,堆空閑歷史最小值,即TotalSz – MinFreeSz?便是堆歷史使用量峰值。
出異常時(shí),可以利用該信息大致判斷堆是否出現(xiàn)空閑內(nèi)存不足的問(wèn)題。
回到問(wèn)題中來(lái),測(cè)試case跑起來(lái)后,循環(huán)輸出了每次網(wǎng)絡(luò)連接后的系統(tǒng)內(nèi)存使用情況,如圖:
....
5. 問(wèn)題定位
可見(jiàn)系統(tǒng)系內(nèi)存經(jīng)過(guò)每次suspend 和 connect后,都會(huì)減少,并且減少的大小是固定的。這種情況是發(fā)生了穩(wěn)定的內(nèi)存泄漏,廠商的WIFI驅(qū)動(dòng)中存在著connect時(shí) malloc的內(nèi)存,在suspend時(shí)沒(méi)有free的情況,導(dǎo)致了內(nèi)存池泄漏,早晚會(huì)發(fā)生內(nèi)存耗盡。
由最早的log可知,系統(tǒng)crach的時(shí)候(也就是內(nèi)存耗盡的時(shí)候),系統(tǒng)中存在著982個(gè)timer沒(méi)有釋放,所以我們重點(diǎn)關(guān)注timer的使用。由于廠商不提供源碼(這也是每次定位問(wèn)題異常痛苦的原因之一),沒(méi)法在上層代碼處直接加打印調(diào)試。在kernel timer處加上打印,結(jié)果如下:connect:
suspend:
可以非常明顯的看出,connect時(shí)timer create了5次,但是suspend的時(shí)候,只delete了4次!
問(wèn)題定位到這里,已經(jīng)明確了問(wèn)題根因:timer少釋放了一次。反饋給廠商后,迅速解決。
6. 總結(jié)
這里結(jié)合使用了AliOS Things維測(cè)能力的幾個(gè)方面:
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的AliOS Things 维测典型案例分析 —— 内存泄漏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 从遇见到信任 | Apache Dubb
- 下一篇: 牛!阿里云位居中国金融云市场第一