鸿蒙轻内核调测-内存调测-内存泄漏检测

1、基础概念

内存泄漏检测机制作为内核的可选功能,用于辅助定位动态内存泄漏问题。开启该功能,动态内存机制会自动记录申请内存时的函数调用关系(下文简称LR)。如果出现泄漏,就可以利用这些记录的信息,找到内存申请的地方,方便进一步确认。

2、功能配置

  • LOSCFG_MEM_LEAKCHECK:开关宏,默认关闭;若打开这个功能,在target_config.h中将这个宏定义为1。
  • LOSCFG_MEM_RECORD_LR_CNT:记录的LR层数,默认3层;每层LR消耗sizeof(void *)字节数的内存。
  • LOSCFG_MEM_OMIT_LR_CNT:忽略的LR层数,默认4层,即从调用LOS_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下:
    • LOS_MemAlloc接口内部也有函数调用;
    • 外部可能对LOS_MemAlloc接口有封装;
    • LOSCFG_MEM_RECORD_LR_CNT 配置的LR层数有限;
      正确配置这个宏,将无效的LR层数忽略,就可以记录有效的LR层数,节省内存消耗。

3、开发指导

3.1开发流程

该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。

调用LOS_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。

node        size   LR[0]      LR[1]       LR[2]  
0x10017320: 0x528 0x9b004eba  0x9b004f60  0x9b005002 
0x10017848: 0xe0  0x9b02c24e  0x9b02c246  0x9b008ef0 
0x10017928: 0x50  0x9b008ed0  0x9b068902  0x9b0687c4 
0x10017978: 0x24  0x9b008ed0  0x9b068924  0x9b0687c4
0x1001799c: 0x30  0x9b02c24e  0x9b02c246  0x9b008ef0 
0x100179cc: 0x5c  0x9b02c24e  0x9b02c246  0x9b008ef0 

注意: 开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。

3.2 编程实例

本实例实现如下功能:构建内存泄漏代码段。

  1. 调用LOS_MemUsedNodeShow接口,输出全部节点信息打印;
  2. 申请内存,但没有释放,模拟内存泄漏;
  3. 再次调用LOS_MemUsedNodeShow接口,输出全部节点信息打印;
  4. 将两次log进行对比,得出泄漏的节点信息;
  5. 通过LR地址,找出泄漏的代码位置;
3.3 示例代码

代码实现如下:

#include <stdio.h>
#include <string.h>
#include "los_memory.h"
#include "los_config.h"

void MemLeakTest(void)
{
    LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR);
    void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
    void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
    LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR);
}
3.3 结果验证

编译运行输出log如下:

node         size   LR[0]       LR[1]       LR[2]   
0x20001b04:  0x24   0x08001a10  0x080035ce  0x080028fc 
0x20002058:  0x40   0x08002fe8  0x08003626  0x080028fc 
0x200022ac:  0x40   0x08000e0c  0x08000e56  0x0800359e 
0x20002594:  0x120  0x08000e0c  0x08000e56  0x08000c8a 
0x20002aac:  0x56   0x08000e0c  0x08000e56  0x08004220 

node         size   LR[0]       LR[1]       LR[2]   
0x20001b04:  0x24   0x08001a10  0x080035ce  0x080028fc 
0x20002058:  0x40   0x08002fe8  0x08003626  0x080028fc 
0x200022ac:  0x40   0x08000e0c  0x08000e56  0x0800359e 
0x20002594:  0x120  0x08000e0c  0x08000e56  0x08000c8a 
0x20002aac:  0x56   0x08000e0c  0x08000e56  0x08004220 
0x20003ac4:  0x1d   0x08001458  0x080014e0  0x080041e6 
0x20003ae0:  0x1d   0x080041ee  0x08000cc2  0x00000000 

对比两次log,差异如下,这些内存节点就是疑似泄漏的内存块:

0x20003ac4:  0x1d   0x08001458  0x080014e0  0x080041e6 
0x20003ae0:  0x1d   0x080041ee  0x08000cc2  0x00000000 

部分汇编文件如下:

                MemLeakTest:
  0x80041d4: 0xb510         PUSH     {R4, LR}
  0x80041d6: 0x4ca8         LDR.N    R4, [PC, #0x2a0]       ; g_memStart
  0x80041d8: 0x0020         MOVS     R0, R4
  0x80041da: 0xf7fd 0xf93e  BL       LOS_MemUsedNodeShow    ; 0x800145a
  0x80041de: 0x2108         MOVS     R1, #8
  0x80041e0: 0x0020         MOVS     R0, R4
  0x80041e2: 0xf7fd 0xfbd9  BL       LOS_MemAlloc           ; 0x8001998
  0x80041e6: 0x2108         MOVS     R1, #8
  0x80041e8: 0x0020         MOVS     R0, R4
  0x80041ea: 0xf7fd 0xfbd5  BL       LOS_MemAlloc           ; 0x8001998
  0x80041ee: 0x0020         MOVS     R0, R4
  0x80041f0: 0xf7fd 0xf933  BL       LOS_MemUsedNodeShow    ; 0x800145a
  0x80041f4: 0xbd10         POP      {R4, PC}
  0x80041f6: 0x0000         MOVS     R0, R0

其中,通过查找0x080041ee,就可以发现该内存节点是在MemLeakTest接口里申请的且是没有释放的。

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ......

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ......

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:https://qr21.cn/FV7h05
相关推荐
dawn1 小时前
鸿蒙ArkTS中的获取网络数据
华为·harmonyos
桃花键神2 小时前
鸿蒙5.0时代:原生鸿蒙应用市场引领开发者服务新篇章
华为·harmonyos
鸿蒙自习室2 小时前
鸿蒙多线程开发——并发模型对比(Actor与内存共享)
华为·harmonyos
JavaPub-rodert3 小时前
鸿蒙生态崛起:开发者的机遇与挑战
华为·harmonyos
帅比九日5 小时前
【HarmonyOS Next】封装一个网络请求模块
前端·harmonyos
yilylong6 小时前
鸿蒙(Harmony)实现滑块验证码
华为·harmonyos·鸿蒙
baby_hua6 小时前
HarmonyOS第一课——DevEco Studio的使用
华为·harmonyos
HarmonyOS_SDK7 小时前
融合虚拟与现实,AR Engine为用户提供沉浸式交互体验
harmonyos
- 羊羊不超越 -8 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
Industio_触觉智能9 小时前
OpenHarmony4.1蓝牙芯片如何适配?触觉智能RK3568主板SBC3568演示
openharmony·rk3568·开源鸿蒙·鸿蒙开发板·触觉智能