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