1# 踩内存检测<a name="ZH-CN_TOPIC_0000001124471131"></a> 2 3- [基础概念](#section17368154517335) 4- [功能配置](#section4696190123420) 5- [开发指导](#section672362973417) 6 - [开发流程](#section026014863416) 7 - [编程实例](#section186311302356) 8 - [示例代码](#section12709533354) 9 - [结果验证](#section81214126369) 10 11 12## 基础概念<a name="section17368154517335"></a> 13 14踩内存检测机制作为内核的可选功能,用于检测动态内存池的完整性。通过该机制,可以及时发现内存池是否发生了踩内存问题,并给出错误信息,便于及时发现系统问题,提高问题解决效率,降低问题定位成本。 15 16## 功能配置<a name="section4696190123420"></a> 17 18LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 19 201. 开启这个功能,每次申请内存,会实时检测内存池的完整性。 212. 如果不开启该功能,也可以调用LOS\_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 22 23由于该功能只会检测出哪个内存节点被破坏了,并给出前节点信息(因为内存分布是连续的,当前节点最有可能被前节点破坏)。如果要进一步确认前节点在哪里申请的,需开启内存泄漏检测功能,通过LR记录,辅助定位。 24 25> **注意:** 26>开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS\_MemIntegrityCheck接口检测。 27 28## 开发指导<a name="section672362973417"></a> 29 30### 开发流程<a name="section026014863416"></a> 31 32通过调用LOS\_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 33 34### 编程实例<a name="section186311302356"></a> 35 36本实例实现如下功能: 37 381. 申请两个物理上连续的内存块; 392. 通过memset构造越界访问,踩到下个节点的头4个字节; 403. 调用LOS\_MemIntegrityCheck检测是否发生踩内存。 41 42### 示例代码<a name="section12709533354"></a> 43 44代码实现如下: 45 46``` 47#include <stdio.h> 48#include <string.h> 49#include "los_memory.h" 50#include "los_config.h" 51 52void MemIntegrityTest(void) 53{ 54 /* 申请两个物理连续的内存块 */ 55 void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); 56 void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); 57 /* 第一个节点内存块大小是8字节,那么12字节的清零,会踩到第二个内存节点的节点头,构造踩内存场景 */ 58 memset(ptr1, 0, 8 + 4); 59 LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR); 60} 61``` 62 63### 结果验证<a name="section81214126369"></a> 64 65编译运行输出log如下: 66 67``` 68[ERR][OsMemMagicCheckPrint], 2028, memory check error! 69memory used but magic num wrong, magic num = 0x00000000 /* 提示信息,检测到哪个字段被破坏了,用例构造了将下个节点的头4个字节清零,即魔鬼数字字段 */ 70 71 broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020 72/* 被破坏节点和其前节点关键字段信息,分别为其前节点地址、节点的魔鬼数字、节点的sizeAndFlag;可以看出被破坏节点的魔鬼数字字段被清零,符合用例场景 */ 73 74 broken node head LR info: /* 节点的LR信息需要开启内存检测功能才有有效输出 */ 75 LR[0]:0x0800414e 76 LR[1]:0x08000cc2 77 LR[2]:0x00000000 78 79 pre node head LR info: /* 通过LR信息,可以在汇编文件中查找前节点是哪里申请,然后排查其使用的准确性 */ 80 LR[0]:0x08004144 81 LR[1]:0x08000cc2 82 LR[2]:0x00000000 83[ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* 被破坏节点和其前节点的地址 */ 84``` 85 86