kernel-lite-mini-inner-debug-cet.md 4.2 KB
Newer Older
D
duangavin123 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# 踩内存检测<a name="ZH-CN_TOPIC_0000001124471131"></a>

-   [基础概念](#section17368154517335)
-   [功能配置](#section4696190123420)
-   [开发指导](#section672362973417)
    -   [开发流程](#section026014863416)
    -   [编程实例](#section186311302356)
    -   [示例代码](#section12709533354)
    -   [结果验证](#section81214126369)


## 基础概念<a name="section17368154517335"></a>

踩内存检测机制作为内核的可选功能,用于检测动态内存池的完整性。通过该机制,可以及时发现内存池是否发生了踩内存问题,并给出错误信息,便于及时发现系统问题,提高问题解决效率,降低问题定位成本。

## 功能配置<a name="section4696190123420"></a>

LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。

1.  开启这个功能,每次申请内存,会实时检测内存池的完整性。
2.  如果不开启该功能,也可以调用LOS\_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。

由于该功能只会检测出哪个内存节点被破坏了,并给出前节点信息(因为内存分布是连续的,当前节点最有可能被前节点破坏)。如果要进一步确认前节点在哪里申请的,需开启内存泄漏检测功能,通过LR记录,辅助定位。

D
duangavin123 已提交
25
>![](../public_sys-resources/icon-caution.gif) **注意:** 
D
duangavin123 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
>开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS\_MemIntegrityCheck接口检测。

## 开发指导<a name="section672362973417"></a>

### 开发流程<a name="section026014863416"></a>

通过调用LOS\_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。

### 编程实例<a name="section186311302356"></a>

本实例实现如下功能:

1.  申请两个物理上连续的内存块;
2.  通过memset构造越界访问,踩到下个节点的头4个字节;
3.  调用LOS\_MemIntegrityCheck检测是否发生踩内存。

### 示例代码<a name="section12709533354"></a>

代码实现如下:

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

void MemIntegrityTest(void)
{
    /* 申请两个物理连续的内存块 */
    void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
    void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
    /* 第一个节点内存块大小是8字节,那么12字节的清零,会踩到第二个内存节点的节点头,构造踩内存场景 */
    memset(ptr1, 0, 8 + 4);
    LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR);
}
```

### 结果验证<a name="section81214126369"></a>

编译运行输出log如下:

```
[ERR][OsMemMagicCheckPrint], 2028, memory check error!
memory used but magic num wrong, magic num = 0x00000000   /* 提示信息,检测到哪个字段被破坏了,用例构造了将下个节点的头4个字节清零,即魔鬼数字字段 */

 broken node head: 0x20003af0  0x00000000  0x80000020, prev node head: 0x20002ad4  0xabcddcba  0x80000020   
/* 被破坏节点和其前节点关键字段信息,分别为其前节点地址、节点的魔鬼数字、节点的sizeAndFlag;可以看出被破坏节点的魔鬼数字字段被清零,符合用例场景 */

 broken node head LR info:  /* 节点的LR信息需要开启内存检测功能才有有效输出 */
 LR[0]:0x0800414e
 LR[1]:0x08000cc2
 LR[2]:0x00000000

 pre node head LR info:   /* 通过LR信息,可以在汇编文件中查找前节点是哪里申请,然后排查其使用的准确性 */
 LR[0]:0x08004144
 LR[1]:0x08000cc2
 LR[2]:0x00000000
[ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0   /* 被破坏节点和其前节点的地址 */
```