IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    为 freertos 的 heap_4 动态内存分配方案增加 heap info 调试信息

    Hacper\'s Blog发表于 2024-06-23 02:00:18
    love 0

    如何为 freertos 的 heap_4 动态内存分配方案增加 heap info 调试信息?

    增加调试信息的目的是为了方便排查内存泄漏和内存越界问题,为了排查内存泄漏,需要记录每个内存块的申请者信息,以下是针对内存泄漏问题调试的修改。

    • 修改内存块头部的数据结构,增加字段记录内存申请者的信息和申请的内存大小。
    1
    2
    3
    4
    5
    6
    7
    
    typedef struct A_BLOCK_LINK
    {
        struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */
        size_t xBlockSize;                     /*<< The size of the free block. */
        size_t xWantedSize;
        void *caller;
    } BlockLink_t;
    

    xWantedSize 和 caller 是新增的字段,分别用于记录内存分配时候的调用者信息和申请的内存大小。

    • 修改 pvPortMalloc 和 pvPortRealloc 的定义,传入参数增加 caller。
    1
    2
    3
    
    void * pvPortMalloc( size_t xSize , void *caller) PRIVILEGED_FUNCTION;
    void * pvPortRealloc( void *p,
                         size_t xSize, void *caller) PRIVILEGED_FUNCTION;
    
    • 修改 prvHeapInit pvPortMalloc 的实现,增加记录 caller,增加新接口 show_heap_info 查看 heap 的内存使用情况。

    在 heap 初始化的时候增加 caller xWantedSize 的初始化。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    
    static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
    {
        BlockLink_t * pxFirstFreeBlock;
        uint8_t * pucAlignedHeap;
        size_t uxAddress;
        size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
    
        /* Ensure the heap starts on a correctly aligned boundary. */
        uxAddress = ( size_t ) ucHeap;
    
        if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
        {
            uxAddress += ( portBYTE_ALIGNMENT - 1 );
            uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
            xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
        }
    
        pucAlignedHeap = ( uint8_t * ) uxAddress;
    
        /* xStart is used to hold a pointer to the first item in the list of free
         * blocks.  The void cast is used to prevent compiler warnings. */
        xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
        xStart.xBlockSize = ( size_t ) 0;
        xStart.caller = NULL;
        xStart.xWantedSize = 0;
    
        /* pxEnd is used to mark the end of the list of free blocks and is inserted
         * at the end of the heap space. */
        uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
        uxAddress -= xHeapStructSize;
        uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
        pxEnd = ( void * ) uxAddress;
        pxEnd->xBlockSize = 0;
        pxEnd->caller = NULL;
        pxEnd->pxNextFreeBlock = NULL;
    
        /* To start with there is a single free block that is sized to take up the
         * entire heap space, minus the space taken by pxEnd. */
        pxFirstFreeBlock = ( void * ) pucAlignedHeap;
        pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
        pxFirstFreeBlock->xWantedSize = 0;
        pxFirstFreeBlock->caller = NULL;
        pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
    
        /* Only one block exists - and it covers the entire usable heap space. */
        xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
        xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
    }
    

    在分配内存的时候,记录caller 和 xWantedSize 到内存卡的头部。

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    
    void * pvPortMalloc( size_t xWantedSize , void * caller)
    {
        BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
        void * pvReturn = NULL;
        size_t xAdditionalRequiredSize;
        size_t _xWantedSize = xWantedSize;
    
        vTaskSuspendAll();
        {
            /* If this is the first call to malloc then the heap will require
             * initialisation to setup the list of free blocks. */
            if( pxEnd == NULL )
            {
                prvHeapInit();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
    
            if( xWantedSize > 0 )
            {
                /* The wanted size must be increased so it can contain a BlockLink_t
                 * structure in addition to the requested amount of bytes. Some
                 * additional increment may also be needed for alignment. */
                xAdditionalRequiredSize = xHeapStructSize  + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
    
                if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
                {
                    xWantedSize += xAdditionalRequiredSize;
                }
                else
                {
                    xWantedSize = 0;
                }
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
    
            /* Check the block size we are trying to allocate is not so large that the
             * top bit is set.  The top bit of the block size member of the BlockLink_t
             * structure is used to determine who owns the block - the application or
             * the kernel, so it must be free. */
            if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
            {
                if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
                {
                    /* Traverse the list from the start (lowest address) block until
                     * one of adequate size is found. */
                    pxPreviousBlock = &xStart;
                    pxBlock = xStart.pxNextFreeBlock;
    
                    while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
                    {
                        pxPreviousBlock = pxBlock;
                        pxBlock = pxBlock->pxNextFreeBlock;
                    }
    
                    /* If the end marker was reached then a block of adequate size
                     * was not found. */
                    if( pxBlock != pxEnd )
                    {
                        /* Return the memory space pointed to - jumping over the
                         * BlockLink_t structure at its start. */
                        pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
    
                        /* This block is being returned for use so must be taken out
                         * of the list of free blocks. */
                        pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
    
                        /* If the block is larger than required it can be split into
                         * two. */
                        if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
                        {
                            /* This block is to be split into two.  Create a new
                             * block following the number of bytes requested. The void
                             * cast is used to prevent byte alignment warnings from the
                             * compiler. */
                            pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
                            configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
    
                            /* Calculate the sizes of two blocks split from the
                             * single block. */
                            pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
                            pxNewBlockLink->xWantedSize = 0;
                            pxNewBlockLink->caller = NULL;
                            pxBlock->xBlockSize = xWantedSize;
    
                            /* Insert the new block into the list of free blocks. */
                            prvInsertBlockIntoFreeList( pxNewBlockLink );
                        }
                        else
                        {
                            mtCOVERAGE_TEST_MARKER();
                        }
    
                        
    
                        xFreeBytesRemaining -= pxBlock->xBlockSize;
                        
    
                        if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
                        {
                            xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
                        }
                        else
                        {
                            mtCOVERAGE_TEST_MARKER();
                        }
    
                  
                        pxBlock->xWantedSize = _xWantedSize;
                        pxBlock->caller = caller;
                        /* The block is being returned - it is allocated and owned
                         * by the application and has no "next" block. */
                        heapALLOCATE_BLOCK( pxBlock );
                        pxBlock->pxNextFreeBlock = NULL;
                        xNumberOfSuccessfulAllocations++;
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
    
            traceMALLOC( pvReturn, xWantedSize );
        }
        xTaskResumeAll();
    
        #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
        {
            if( pvReturn == NULL )
            {
                vApplicationMallocFailedHook();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
    
        configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
        return pvReturn;
    }
    
    void *pvPortRealloc(void *p,
                        size_t xSize, void * caller)
    {
        void *pv = NULL;
        uint8_t *puc = (uint8_t *)p;
        BlockLink_t *pxLink;
    
        if (p == NULL)
        {
            return NULL;
        }
    
        puc -= xHeapStructSize;
        pxLink = (void *)puc;
    
        configASSERT(heapBLOCK_IS_ALLOCATED(pxLink) != 0);
        configASSERT(pxLink->pxNextFreeBlock == NULL);
    
        pv = pvPortMalloc(xSize, caller);
        if (pv == NULL)
        {
            return NULL;
        }
        memcpy(pv, p, pxLink->xWantedSize);
        vPortFree(p);
    
        return pv;   
    }
    

    遍历 heap 所有的内存块,打印出其调用者、申请内存大小、是已分配的内存块还是空闲的内存块,利用这些信息排查内存泄漏。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
    void show_heap_info(void)
    {
        BlockLink_t * pxLink = NULL;
        uint8_t * pucAlignedHeap;
        size_t uxAddress;
        size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
    
        vTaskSuspendAll();
        uxAddress = ( size_t ) ucHeap;
    
        if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
        {
            uxAddress += ( portBYTE_ALIGNMENT - 1 );
            uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
            xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
        }
    
        pucAlignedHeap = ( uint8_t * ) uxAddress;
    
        pxLink = (BlockLink_t *)pucAlignedHeap;
    
        printf("\r\naddress: 0x%p\r\nsize: %d\r\navail: %d\r\npool_start: 0x%p\r\npool_end: 0x%p\r\n",
               ucHeap, xTotalHeapSize, xFreeBytesRemaining, pucAlignedHeap, pxEnd);
    
        printf("state,block_addr,user_addr,caller,blocksize,wanted_size\r\n");
     
        while (pxLink != pxEnd)
        {
    		
            printf("%s, 0x%p, 0x%p, 0x%p,%d,%d\r\n", ((pxLink->xBlockSize & heapBLOCK_ALLOCATED_BITMASK)!=0)? "U":"F", pxLink, (uint8_t *)pxLink+xHeapStructSize, pxLink->caller, (( pxLink->xBlockSize ) & ~heapBLOCK_ALLOCATED_BITMASK), pxLink->xWantedSize);
            pxLink =(BlockLink_t *) (( uint8_t * )pxLink + (( pxLink->xBlockSize ) & ~heapBLOCK_ALLOCATED_BITMASK));
        }
    
        xTaskResumeAll();
    }
    
    • 利用库打桩机制,替换标准库中的 malloc free realloc 等内存分配函数。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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
    
    
    /************** wrap C library functions **************/
    void * __wrap_malloc (size_t size)
    {
        void *caller = __builtin_return_address (0);
    	return pvPortMalloc(size, caller);
    }
    
    void * __wrap__malloc_r (void *p, size_t size)
    {
    	void *caller = __builtin_return_address (0);
    	return pvPortMalloc(size, caller);
    }
    
    void __wrap_free (void *pv)
    {
    	vPortFree(pv);
    }
    
    void * __wrap_calloc (size_t a, size_t b)
    {
    	void *pvReturn;
        void *caller = __builtin_return_address (0);
        pvReturn = pvPortMalloc( a*b, caller);
        if (pvReturn)
        {
            memset(pvReturn, 0, a*b);
        }
    
        return pvReturn;
    }
    
    void * __wrap_realloc (void* pv, size_t size)
    {
        void *caller = __builtin_return_address (0);
    	return pvPortRealloc(pv, size, caller);
    }
    
    void __wrap__free_r (void *p, void *x)
    {
      __wrap_free(x);
    }
    
    void* __wrap__realloc_r (void *p, void* x, size_t sz)
    {
        void *caller = __builtin_return_address (0);
    	return pvPortRealloc(x, sz, caller);
    }
    
    /*-----------------------------------------------------------*/
    

    gcc 的链接器支持用 –wrap f 参数进行链接时打桩,这个参数告诉链接器,把对符号 f 的引用解析成 __wrap_f。通过这个机制,我们调用malloc的时候,便会替换成我们加了调试信息的__wrap_malloc。另外,再使用 __builtin_return_address 接口获取函数的返回地址并记录,这样就知道是谁申请了这块内存。

    最后再添加连接器参数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    sdk_add_link_options(
            -Wl,--wrap=malloc
            -Wl,--wrap=_malloc_r
            -Wl,--wrap=free
            -Wl,--wrap=calloc
            -Wl,--wrap=realloc
            -Wl,--wrap=_free_r
            -Wl,--wrap=_realloc_r
    )
    

    对于内存越界问题,可以在每个内存块的末尾增加冗余长度,并填充特定数据,在内存释放的时候检查填充的数据有没有被篡改,以此判断是否存在内存被破坏问题。

    • pvPortMalloc 的修改

    在 xWantedSize 的基础上增加一个字节,确保内存块的尾部够空间填充一个特殊数据。然后在将要分配出去的内存块中末尾未使用的数据全部填充为0xfd,填充的长度为 pxBlock->xBlockSize-_xWantedSize-xHeapStructSize。

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    
    void * pvPortMalloc( size_t xWantedSize , void * caller)
    {
        BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
        void * pvReturn = NULL;
        size_t xAdditionalRequiredSize;
        size_t _xWantedSize = xWantedSize;
    
        vTaskSuspendAll();
        {
            /* If this is the first call to malloc then the heap will require
             * initialisation to setup the list of free blocks. */
            if( pxEnd == NULL )
            {
                prvHeapInit();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
    
            if( xWantedSize > 0 )
            {
                /* The wanted size must be increased so it can contain a BlockLink_t
                 * structure in addition to the requested amount of bytes. Some
                 * additional increment may also be needed for alignment. */
                xWantedSize += 1;
                xAdditionalRequiredSize = xHeapStructSize  + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
    
                if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
                {
                    xWantedSize += xAdditionalRequiredSize;
                }
                else
                {
                    xWantedSize = 0;
                }
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
    
            /* Check the block size we are trying to allocate is not so large that the
             * top bit is set.  The top bit of the block size member of the BlockLink_t
             * structure is used to determine who owns the block - the application or
             * the kernel, so it must be free. */
            if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
            {
                if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
                {
                    /* Traverse the list from the start (lowest address) block until
                     * one of adequate size is found. */
                    pxPreviousBlock = &xStart;
                    pxBlock = xStart.pxNextFreeBlock;
    
                    while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
                    {
                        pxPreviousBlock = pxBlock;
                        pxBlock = pxBlock->pxNextFreeBlock;
                    }
    
                    /* If the end marker was reached then a block of adequate size
                     * was not found. */
                    if( pxBlock != pxEnd )
                    {
                        /* Return the memory space pointed to - jumping over the
                         * BlockLink_t structure at its start. */
                        pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
    
                        /* This block is being returned for use so must be taken out
                         * of the list of free blocks. */
                        pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
    
                        /* If the block is larger than required it can be split into
                         * two. */
                        if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
                        {
                            /* This block is to be split into two.  Create a new
                             * block following the number of bytes requested. The void
                             * cast is used to prevent byte alignment warnings from the
                             * compiler. */
                            pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
                            configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
    
                            /* Calculate the sizes of two blocks split from the
                             * single block. */
                            pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
                            pxNewBlockLink->xWantedSize = 0;
                            pxNewBlockLink->caller = NULL;
                            pxBlock->xBlockSize = xWantedSize;
    
                            /* Insert the new block into the list of free blocks. */
                            prvInsertBlockIntoFreeList( pxNewBlockLink );
                        }
                        else
                        {
                            mtCOVERAGE_TEST_MARKER();
                        }
    
                        
    
                        xFreeBytesRemaining -= pxBlock->xBlockSize;
                        
    
                        if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
                        {
                            xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
                        }
                        else
                        {
                            mtCOVERAGE_TEST_MARKER();
                        }
    
                  
                        pxBlock->xWantedSize = _xWantedSize;
                        pxBlock->caller = caller;
                        int _len = pxBlock->xBlockSize-_xWantedSize-xHeapStructSize;
    					uint8_t *_p = (uint8_t *)pxBlock+_xWantedSize+xHeapStructSize;
    					while (_len > 0)
    					{
    						*_p = 0xfd;
    						_p++;
    						_len--;
    					}
    
                        /* The block is being returned - it is allocated and owned
                         * by the application and has no "next" block. */
                        heapALLOCATE_BLOCK( pxBlock );
                        pxBlock->pxNextFreeBlock = NULL;
                        xNumberOfSuccessfulAllocations++;
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
    
            traceMALLOC( pvReturn, xWantedSize );
        }
        xTaskResumeAll();
    
        #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
        {
            if( pvReturn == NULL )
            {
                vApplicationMallocFailedHook();
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
    
        configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
        return pvReturn;
    }
    

    在释放内存的时候检查内存块的填充数据是否有被篡改,如果有被篡改则说明出现了内存越界问题,可以打印当前内存块的 caller 信息和 dump 整个 block 数据,然后立再触发 ASSERT。 除了在内存释放的时候检查heap是否有越界,也可以在任务上下文切换的时候检查,不过这样会增加任务调度的开销,影响任务切换的效率。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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
    
    
    void vPortFree( void * pv )
    {
        uint8_t * puc = ( uint8_t * ) pv;
        BlockLink_t * pxLink;
    
        if( pv != NULL )
        {
            /* The memory being freed will have an BlockLink_t structure immediately
             * before it. */
            puc -= xHeapStructSize;
    
            /* This casting is to keep the compiler from issuing warnings. */
            pxLink = ( void * ) puc;
    
            configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
            configASSERT( pxLink->pxNextFreeBlock == NULL );
    
            if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
            {
                if( pxLink->pxNextFreeBlock == NULL )
                {
                    /* The block is being returned to the heap - it is no longer
                     * allocated. */
                    heapFREE_BLOCK( pxLink );
                    #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
                    {
                        ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize );
                    }
                    #endif
    
                    vTaskSuspendAll();
                    int _len = pxLink->xBlockSize - pxLink->xWantedSize - xHeapStructSize;
    				uint8_t *_p = (uint8_t *)pxLink + pxLink->xWantedSize + xHeapStructSize;
    				while (_len > 0)
    				{
    					if(*_p != 0xfd)
    					{
    						printf("mem crash,block:0x%p,caller: 0x%p, 0x%02x\r\n", pxLink, pxLink->caller, *_p);
    					}
    					configASSERT( (*_p == 0xfd ) );
    					_p++;
    					_len--;
    				}
    
                    {
                        /* Add this block to the list of free blocks. */
                        xFreeBytesRemaining += pxLink->xBlockSize;
                        traceFREE( pv, pxLink->xBlockSize );
                        pxLink->xWantedSize = 0;
                        prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
                        xNumberOfSuccessfulFrees++;
                    }
                    /*( void ) */xTaskResumeAll();
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
    }
    

    增加 heap info 信息会增加内存分配的开销,导致实际可以使用的 heap 内存变小,在内存较小的机器,应在正式软件上关闭 heap info 信息,以节省内存。

    heap info 调试案例

    内存泄漏问题案例

    打开 mqtt 之前的 heap info:

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    
    address: 0x40aae8
    size: 152856
    avail: 45288
    pool_start: 0x40aae8
    pool_end: 0x42fff0
    state,block_addr,user_addr,caller,blocksize,wanted_size
    U,0x40aae8,0x40abe8,0x1b695,4112,4096
    U,0x40baf8,0x40bbf8,0x1b6b5,40,20
    U,0x40bb20,0x40bc20,0x1b695,528,512
    U,0x40bd30,0x40be30,0x1b6b5,40,20
    U,0x40bd58,0x40be58,0x1b695,4112,4096
    U,0x40cd68,0x40ce68,0x1b6b5,40,20
    U,0x40cd90,0x40ce90,0x1b695,528,512
    U,0x40cfa0,0x40d0a0,0x1b6b5,40,20
    U,0x40cfc8,0x40d0c8,0x7eab8,96,80
    U,0x40d028,0x40d128,0x7e8ac,96,80
    U,0x40d088,0x40d188,0x28319,112,92
    U,0x40d0f8,0x40d1f8,0x28441,96,80
    U,0x40d158,0x40d258,0x7eab8,96,80
    U,0x40d1b8,0x40d2b8,0x7eab8,96,80
    U,0x40d218,0x40d318,0x28319,112,92
    U,0x40d288,0x40d388,0x28441,96,80
    U,0x40d2e8,0x40d3e8,0x7eab8,96,80
    U,0x40d348,0x40d448,0x7eab8,96,80
    U,0x40d3a8,0x40d4a8,0x28319,112,92
    U,0x40d418,0x40d518,0x28441,96,80
    U,0x40d478,0x40d578,0x7eab8,96,80
    U,0x40d4d8,0x40d5d8,0x7eab8,96,80
    U,0x40d538,0x40d638,0x803f4,112,92
    U,0x40d5a8,0x40d6a8,0xa4be5,56,36
    U,0x40d5e0,0x40d6e0,0x9fb53,48,28
    U,0x40d610,0x40d710,0xb22f3,760,744
    U,0x40d908,0x40da08,0x7f51c,1040,1024
    U,0x40dd18,0x40de18,0x7f51c,112,92
    U,0x40dd88,0x40de88,0x7fe1c,288,272
    U,0x40dea8,0x40dfa8,0x7fefc,3088,3072
    U,0x40eab8,0x40ebb8,0x7fefc,112,92
    U,0x40eb28,0x40ec28,0x15769,32,16
    U,0x40eb48,0x40ec48,0x15789,128,108
    U,0x40ebc8,0x40ecc8,0x157a9,136,114
    U,0x40ec50,0x40ed50,0x80808,120,100
    U,0x40ecc8,0x40edc8,0x803f4,1040,1024
    U,0x40f0d8,0x40f1d8,0x803f4,112,92
    U,0x40f148,0x40f248,0x7e8ac,96,80
    U,0x40f1a8,0x40f2a8,0x803f4,4112,4096
    U,0x4101b8,0x4102b8,0x803f4,112,92
    U,0x410228,0x410328,0x28441,96,80
    U,0x410288,0x410388,0x1405f,64,40
    U,0x4102c8,0x4103c8,0xa01ef,40,22
    U,0x4102f0,0x4103f0,0x80c7c,72,44
    U,0x410338,0x410438,0x83c1b,24,8
    U,0x410350,0x410450,0x83c1b,40,4
    U,0x410378,0x410478,0xa1b0d,64,32
    U,0x4103b8,0x4104b8,0x34f21,1040,1024
    U,0x4107c8,0x4108c8,0x9f79d,40,9
    U,0x4107f0,0x4108f0,0x9a079,192,172
    U,0x4108b0,0x4109b0,0x9bf95,40,22
    U,0x4108d8,0x4109d8,0x99f8f,224,208
    U,0x4109b8,0x410ab8,0x9c46f,64,48
    U,0x4109f8,0x410af8,0x9dfef,40,22
    U,0x410a20,0x410b20,0x6e705,32,9
    U,0x410a40,0x410b40,0xa01ef,56,22
    U,0x410a78,0x410b78,0x7eab8,96,80
    U,0x410ad8,0x410bd8,0x7eab8,96,80
    U,0x410b38,0x410c38,0x28319,224,208
    U,0x410c18,0x410d18,0x7eab8,96,80
    U,0x410c78,0x410d78,0x285a9,2064,2048
    U,0x411488,0x411588,0x285a9,112,92
    U,0x4114f8,0x4115f8,0x80808,1120,1104
    U,0x411958,0x411a58,0x803f4,4112,4096
    U,0x412968,0x412a68,0x803f4,112,92
    U,0x4129d8,0x412ad8,0x9d659,72,52
    U,0x412a20,0x412b20,0x7e8ac,96,80
    U,0x412a80,0x412b80,0x80808,1632,1616
    U,0x4130e0,0x4131e0,0x803f4,2064,2048
    U,0x4138f0,0x4139f0,0x803f4,112,92
    U,0x413960,0x413a60,0x80808,256,240
    U,0x413a60,0x413b60,0x803f4,1168,1152
    U,0x413ef0,0x413ff0,0xa46c5,952,936
    U,0x4142a8,0x4143a8,0xb1ff7,56,4
    U,0x4142e0,0x4143e0,0x80808,176,160
    U,0x414390,0x414490,0x803f4,4112,4096
    U,0x4153a0,0x4154a0,0x803f4,112,92
    U,0x415410,0x415510,0x7e8ac,96,80
    U,0x415470,0x415570,0x803f4,112,92
    U,0x4154e0,0x4155e0,0x80808,1296,1280
    U,0x4159f0,0x415af0,0x803f4,112,92
    U,0x415a60,0x415b60,0x7eab8,96,80
    U,0x415ac0,0x415bc0,0x7e8ac,96,80
    U,0x415b20,0x415c20,0x803f4,136,92
    U,0x415ba8,0x415ca8,0x1405f,56,40
    U,0x415be0,0x415ce0,0x1405f,56,40
    U,0x415c18,0x415d18,0x13ed5,24,5
    U,0x415c30,0x415d30,0x1405f,56,40
    U,0x415c68,0x415d68,0x13ed5,24,8
    U,0x415c80,0x415d80,0x1405f,56,40
    U,0x415cb8,0x415db8,0x13ed5,24,7
    U,0x415cd0,0x415dd0,0x1405f,56,40
    U,0x415d08,0x415e08,0x13ed5,24,2
    U,0x415d20,0x415e20,0x1405f,56,40
    U,0x415d58,0x415e58,0x13ed5,24,7
    U,0x415d70,0x415e70,0x1405f,56,40
    U,0x415da8,0x415ea8,0x13ed5,32,12
    U,0x415dc8,0x415ec8,0x1405f,56,40
    U,0x415e00,0x415f00,0x13ed5,24,8
    U,0x415e18,0x415f18,0x1405f,56,40
    U,0x415e50,0x415f50,0x13ed5,32,11
    U,0x415e70,0x415f70,0x13ed5,32,12
    U,0x415e90,0x415f90,0x1405f,56,40
    U,0x415ec8,0x415fc8,0x13ed5,32,13
    U,0x415ee8,0x415fe8,0x13ed5,56,33
    U,0x415f20,0x416020,0x1405f,56,40
    U,0x415f58,0x416058,0x13ed5,32,11
    U,0x415f78,0x416078,0x13ed5,24,8
    U,0x415f90,0x416090,0x1405f,56,40
    U,0x415fc8,0x4160c8,0x13ed5,24,7
    U,0x415fe0,0x4160e0,0x1405f,56,40
    U,0x416018,0x416118,0x13ed5,24,4
    U,0x416030,0x416130,0x1405f,56,40
    U,0x416068,0x416168,0x13ed5,24,2
    U,0x416080,0x416180,0x13ed5,32,12
    U,0x4160a0,0x4161a0,0x1405f,56,40
    U,0x4160d8,0x4161d8,0x13ed5,24,2
    U,0x4160f0,0x4161f0,0x13ed5,32,13
    U,0x416110,0x416210,0x1405f,56,40
    U,0x416148,0x416248,0x13ed5,24,4
    U,0x416160,0x416260,0x1405f,56,40
    U,0x416198,0x416298,0x13ed5,24,2
    U,0x4161b0,0x4162b0,0x13ed5,32,12
    U,0x4161d0,0x4162d0,0x1405f,56,40
    U,0x416208,0x416308,0x13ed5,24,2
    U,0x416220,0x416320,0x13ed5,32,13
    U,0x416240,0x416340,0x1405f,56,40
    U,0x416278,0x416378,0x13ed5,24,4
    U,0x416290,0x416390,0x1405f,56,40
    U,0x4162c8,0x4163c8,0x13ed5,24,2
    U,0x4162e0,0x4163e0,0x1405f,56,40
    U,0x416318,0x416418,0x13ed5,24,8
    U,0x416330,0x416430,0x1405f,56,40
    U,0x416368,0x416468,0x13ed5,32,11
    U,0x416388,0x416488,0x13ed5,32,12
    U,0x4163a8,0x4164a8,0x1405f,56,40
    U,0x4163e0,0x4164e0,0x13ed5,32,13
    U,0x416400,0x416500,0x13ed5,56,33
    U,0x416438,0x416538,0x1405f,56,40
    U,0x416470,0x416570,0x13ed5,32,11
    U,0x416490,0x416590,0x13ed5,24,8
    U,0x4164a8,0x4165a8,0x1405f,56,40
    U,0x4164e0,0x4165e0,0x13ed5,24,7
    U,0x4164f8,0x4165f8,0x1405f,56,40
    U,0x416530,0x416630,0x13ed5,32,12
    U,0x416550,0x416650,0x1405f,56,40
    U,0x416588,0x416688,0x13ed5,24,7
    U,0x4165a0,0x4166a0,0x1405f,56,40
    U,0x4165d8,0x4166d8,0x13ed5,24,4
    U,0x4165f0,0x4166f0,0x1405f,56,40
    U,0x416628,0x416728,0x13ed5,24,2
    U,0x416640,0x416740,0x13ed5,40,19
    U,0x416668,0x416768,0x1405f,56,40
    U,0x4166a0,0x4167a0,0x13ed5,24,2
    U,0x4166b8,0x4167b8,0x13ed5,32,12
    U,0x4166d8,0x4167d8,0x1405f,56,40
    U,0x416710,0x416810,0x13ed5,24,4
    U,0x416728,0x416828,0x1405f,56,40
    U,0x416760,0x416860,0x13ed5,24,2
    U,0x416778,0x416878,0x13ed5,40,19
    U,0x4167a0,0x4168a0,0x1405f,56,40
    U,0x4167d8,0x4168d8,0x13ed5,24,2
    U,0x4167f0,0x4168f0,0x13ed5,32,12
    U,0x416810,0x416910,0x1405f,56,40
    U,0x416848,0x416948,0x13ed5,24,4
    U,0x416860,0x416960,0x1405f,56,40
    U,0x416898,0x416998,0x13ed5,24,2
    U,0x4168b0,0x4169b0,0x1405f,56,40
    U,0x4168e8,0x4169e8,0x13ed5,24,8
    U,0x416900,0x416a00,0x1405f,56,40
    U,0x416938,0x416a38,0x13ed5,32,11
    U,0x416958,0x416a58,0x13ed5,32,12
    U,0x416978,0x416a78,0x1405f,56,40
    U,0x4169b0,0x416ab0,0x13ed5,32,13
    U,0x4169d0,0x416ad0,0x13ed5,56,33
    U,0x416a08,0x416b08,0x1405f,56,40
    U,0x416a40,0x416b40,0x13ed5,32,11
    U,0x416a60,0x416b60,0x13ed5,24,8
    U,0x416a78,0x416b78,0x1405f,56,40
    U,0x416ab0,0x416bb0,0x13ed5,24,7
    U,0x416ac8,0x416bc8,0x1405f,56,40
    U,0x416b00,0x416c00,0x13ed5,32,12
    U,0x416b20,0x416c20,0x1405f,56,40
    U,0x416b58,0x416c58,0x13ed5,24,7
    U,0x416b70,0x416c70,0x1405f,56,40
    U,0x416ba8,0x416ca8,0x13ed5,24,4
    U,0x416bc0,0x416cc0,0x1405f,56,40
    U,0x416bf8,0x416cf8,0x13ed5,24,2
    U,0x416c10,0x416d10,0x13ed5,40,19
    U,0x416c38,0x416d38,0x1405f,56,40
    U,0x416c70,0x416d70,0x13ed5,24,2
    U,0x416c88,0x416d88,0x13ed5,40,20
    U,0x416cb0,0x416db0,0x1405f,56,40
    U,0x416ce8,0x416de8,0x13ed5,24,4
    U,0x416d00,0x416e00,0x1405f,56,40
    U,0x416d38,0x416e38,0x13ed5,24,2
    U,0x416d50,0x416e50,0x13ed5,40,19
    U,0x416d78,0x416e78,0x1405f,56,40
    U,0x416db0,0x416eb0,0x13ed5,24,2
    U,0x416dc8,0x416ec8,0x13ed5,40,20
    U,0x416df0,0x416ef0,0x1405f,56,40
    U,0x416e28,0x416f28,0x13ed5,24,4
    U,0x416e40,0x416f40,0x1405f,56,40
    U,0x416e78,0x416f78,0x13ed5,24,2
    U,0x416e90,0x416f90,0x1405f,56,40
    U,0x416ec8,0x416fc8,0x13ed5,24,8
    U,0x416ee0,0x416fe0,0x1405f,56,40
    U,0x416f18,0x417018,0x13ed5,32,11
    U,0x416f38,0x417038,0x13ed5,32,12
    U,0x416f58,0x417058,0x1405f,56,40
    U,0x416f90,0x417090,0x13ed5,32,13
    U,0x416fb0,0x4170b0,0x13ed5,56,33
    U,0x416fe8,0x4170e8,0x1405f,56,40
    U,0x417020,0x417120,0x13ed5,32,11
    U,0x417040,0x417140,0x13ed5,32,13
    U,0x417060,0x417160,0x1405f,56,40
    U,0x417098,0x417198,0x13ed5,24,7
    U,0x4170b0,0x4171b0,0x1405f,56,40
    U,0x4170e8,0x4171e8,0x13ed5,32,12
    U,0x417108,0x417208,0x1405f,56,40
    U,0x417140,0x417240,0x13ed5,24,7
    U,0x417158,0x417258,0x1405f,56,40
    U,0x417190,0x417290,0x13ed5,24,4
    U,0x4171a8,0x4172a8,0x1405f,56,40
    U,0x4171e0,0x4172e0,0x13ed5,24,2
    U,0x4171f8,0x4172f8,0x13ed5,40,21
    U,0x417220,0x417320,0x1405f,56,40
    U,0x417258,0x417358,0x13ed5,24,2
    U,0x417270,0x417370,0x13ed5,40,22
    U,0x417298,0x417398,0x1405f,56,40
    U,0x4172d0,0x4173d0,0x13ed5,24,4
    U,0x4172e8,0x4173e8,0x1405f,56,40
    U,0x417320,0x417420,0x13ed5,24,2
    U,0x417338,0x417438,0x13ed5,40,21
    U,0x417360,0x417460,0x1405f,56,40
    U,0x417398,0x417498,0x13ed5,24,2
    U,0x4173b0,0x4174b0,0x13ed5,40,22
    U,0x4173d8,0x4174d8,0x1405f,56,40
    U,0x417410,0x417510,0x13ed5,24,4
    U,0x417428,0x417528,0x1405f,56,40
    U,0x417460,0x417560,0x13ed5,24,2
    U,0x417478,0x417578,0x1405f,56,40
    U,0x4174b0,0x4175b0,0x13ed5,24,8
    U,0x4174c8,0x4175c8,0x1405f,56,40
    U,0x417500,0x417600,0x13ed5,32,11
    U,0x417520,0x417620,0x13ed5,32,12
    U,0x417540,0x417640,0x1405f,56,40
    U,0x417578,0x417678,0x13ed5,32,13
    U,0x417598,0x417698,0x13ed5,56,33
    U,0x4175d0,0x4176d0,0x1405f,56,40
    U,0x417608,0x417708,0x13ed5,32,11
    U,0x417628,0x417728,0x13ed5,32,13
    U,0x417648,0x417748,0x1405f,56,40
    U,0x417680,0x417780,0x13ed5,24,7
    U,0x417698,0x417798,0x1405f,56,40
    U,0x4176d0,0x4177d0,0x13ed5,32,12
    U,0x4176f0,0x4177f0,0x1405f,56,40
    U,0x417728,0x417828,0x13ed5,24,7
    U,0x417740,0x417840,0x1405f,56,40
    U,0x417778,0x417878,0x13ed5,24,4
    U,0x417790,0x417890,0x1405f,56,40
    U,0x4177c8,0x4178c8,0x13ed5,24,2
    U,0x4177e0,0x4178e0,0x13ed5,40,21
    U,0x417808,0x417908,0x1405f,56,40
    U,0x417840,0x417940,0x13ed5,24,2
    U,0x417858,0x417958,0x13ed5,40,22
    U,0x417880,0x417980,0x1405f,56,40
    U,0x4178b8,0x4179b8,0x13ed5,24,4
    U,0x4178d0,0x4179d0,0x1405f,56,40
    U,0x417908,0x417a08,0x13ed5,24,2
    U,0x417920,0x417a20,0x13ed5,40,21
    U,0x417948,0x417a48,0x1405f,56,40
    U,0x417980,0x417a80,0x13ed5,24,2
    U,0x417998,0x417a98,0x13ed5,40,22
    U,0x4179c0,0x417ac0,0x1405f,56,40
    U,0x4179f8,0x417af8,0x13ed5,24,4
    U,0x417a10,0x417b10,0x1405f,56,40
    U,0x417a48,0x417b48,0x13ed5,24,8
    U,0x417a60,0x417b60,0x1405f,56,40
    U,0x417a98,0x417b98,0x1405f,56,40
    U,0x417ad0,0x417bd0,0x13ed5,24,8
    U,0x417ae8,0x417be8,0x1405f,56,40
    U,0x417b20,0x417c20,0x13ed5,32,9
    U,0x417b40,0x417c40,0x1405f,56,40
    U,0x417b78,0x417c78,0x13ed5,32,9
    U,0x417b98,0x417c98,0x1405f,56,40
    U,0x417bd0,0x417cd0,0x13ed5,24,6
    U,0x417be8,0x417ce8,0x1405f,56,40
    U,0x417c20,0x417d20,0x1405f,56,40
    U,0x417c58,0x417d58,0x13ed5,24,8
    U,0x417c70,0x417d70,0x1405f,56,40
    U,0x417ca8,0x417da8,0x13ed5,32,9
    U,0x417cc8,0x417dc8,0x1405f,56,40
    U,0x417d00,0x417e00,0x13ed5,32,9
    U,0x417d20,0x417e20,0x1405f,56,40
    U,0x417d58,0x417e58,0x13ed5,24,6
    U,0x417d70,0x417e70,0x1405f,56,40
    U,0x417da8,0x417ea8,0x1405f,56,40
    U,0x417de0,0x417ee0,0x13ed5,24,8
    U,0x417df8,0x417ef8,0x1405f,56,40
    U,0x417e30,0x417f30,0x13ed5,32,9
    U,0x417e50,0x417f50,0x1405f,56,40
    U,0x417e88,0x417f88,0x13ed5,32,9
    U,0x417ea8,0x417fa8,0x1405f,56,40
    U,0x417ee0,0x417fe0,0x13ed5,24,6
    U,0x417ef8,0x417ff8,0x1405f,56,40
    U,0x417f30,0x418030,0x1405f,56,40
    U,0x417f68,0x418068,0x13ed5,24,8
    U,0x417f80,0x418080,0x1405f,56,40
    U,0x417fb8,0x4180b8,0x13ed5,32,9
    U,0x417fd8,0x4180d8,0x1405f,56,40
    U,0x418010,0x418110,0x13ed5,32,9
    U,0x418030,0x418130,0x1405f,56,40
    U,0x418068,0x418168,0x13ed5,24,6
    U,0x418080,0x418180,0x1405f,56,40
    U,0x4180b8,0x4181b8,0x1405f,56,40
    U,0x4180f0,0x4181f0,0x13ed5,24,8
    U,0x418108,0x418208,0x1405f,56,40
    U,0x418140,0x418240,0x13ed5,32,9
    U,0x418160,0x418260,0x1405f,56,40
    U,0x418198,0x418298,0x13ed5,32,9
    F,0x4181b8,0x4182b8,0x9594d,80,63
    U,0x418208,0x418308,0x1405f,56,40
    U,0x418240,0x418340,0x13ed5,32,10
    U,0x418260,0x418360,0x1405f,56,40
    U,0x418298,0x418398,0x13ed5,24,2
    U,0x4182b0,0x4183b0,0x1405f,56,40
    U,0x4182e8,0x4183e8,0x13ed5,32,9
    U,0x418308,0x418408,0x1405f,56,40
    U,0x418340,0x418440,0x13ed5,24,5
    U,0x418358,0x418458,0x1405f,56,40
    U,0x418390,0x418490,0x13ed5,24,8
    U,0x4183a8,0x4184a8,0x1405f,56,40
    U,0x4183e0,0x4184e0,0x13ed5,24,5
    U,0x4183f8,0x4184f8,0x1405f,56,40
    U,0x418430,0x418530,0x13ed5,24,5
    U,0x418448,0x418548,0x13ed5,24,1
    U,0x418460,0x418560,0x1405f,56,40
    U,0x418498,0x418598,0x13ed5,24,7
    U,0x4184b0,0x4185b0,0x1405f,56,40
    U,0x4184e8,0x4185e8,0x13ed5,24,2
    U,0x418500,0x418600,0x1405f,56,40
    U,0x418538,0x418638,0x13ed5,32,9
    U,0x418558,0x418658,0x1405f,56,40
    U,0x418590,0x418690,0x13ed5,24,5
    U,0x4185a8,0x4186a8,0x1405f,56,40
    U,0x4185e0,0x4186e0,0x13ed5,24,8
    U,0x4185f8,0x4186f8,0x1405f,56,40
    U,0x418630,0x418730,0x13ed5,24,5
    U,0x418648,0x418748,0x1405f,56,40
    U,0x418680,0x418780,0x13ed5,24,5
    U,0x418698,0x418798,0x13ed5,24,1
    U,0x4186b0,0x4187b0,0x1405f,56,40
    U,0x4186e8,0x4187e8,0x13ed5,24,7
    U,0x418700,0x418800,0x1405f,56,40
    U,0x418738,0x418838,0x13ed5,24,2
    U,0x418750,0x418850,0x1405f,56,40
    U,0x418788,0x418888,0x13ed5,32,9
    U,0x4187a8,0x4188a8,0x1405f,56,40
    U,0x4187e0,0x4188e0,0x13ed5,24,5
    U,0x4187f8,0x4188f8,0x1405f,56,40
    U,0x418830,0x418930,0x13ed5,24,8
    U,0x418848,0x418948,0x1405f,56,40
    U,0x418880,0x418980,0x13ed5,24,5
    U,0x418898,0x418998,0x1405f,56,40
    U,0x4188d0,0x4189d0,0x13ed5,24,5
    U,0x4188e8,0x4189e8,0x13ed5,24,1
    U,0x418900,0x418a00,0x1405f,56,40
    U,0x418938,0x418a38,0x13ed5,24,7
    U,0x418950,0x418a50,0x3dc13,2720,2704
    U,0x4193f0,0x4194f0,0x803f4,3088,3072
    U,0x41a000,0x41a100,0x803f4,3088,3072
    U,0x41ac10,0x41ad10,0x80808,896,880
    U,0x41af90,0x41b090,0x803f4,1040,1024
    U,0x41b3a0,0x41b4a0,0x803f4,12304,12288
    U,0x41e3b0,0x41e4b0,0x803f4,112,92
    U,0x41e420,0x41e520,0x80808,1296,1280
    U,0x41e930,0x41ea30,0x803f4,5136,5120
    U,0x41fd40,0x41fe40,0x803f4,112,92
    U,0x41fdb0,0x41feb0,0x803f4,4112,4096
    U,0x420dc0,0x420ec0,0x803f4,112,92
    F,0x420e30,0x420f30,0x956db,64,36
    U,0x420e70,0x420f70,0x42d97,40,20
    U,0x420e98,0x420f98,0x7eab8,96,80
    U,0x420ef8,0x420ff8,0x42d97,40,20
    U,0x420f20,0x421020,0x7eab8,96,80
    U,0x420f80,0x421080,0x42d97,40,20
    U,0x420fa8,0x4210a8,0x7eab8,96,80
    U,0x421008,0x421108,0x42d97,40,20
    U,0x421030,0x421130,0x7eab8,96,80
    U,0x421090,0x421190,0x42d97,40,20
    U,0x4210b8,0x4211b8,0x7eab8,96,80
    U,0x421118,0x421218,0x42d97,40,20
    U,0x421140,0x421240,0x7eab8,96,80
    U,0x4211a0,0x4212a0,0x7eab8,96,80
    U,0x421200,0x421300,0x80c7c,64,44
    U,0x421240,0x421340,0x7e8ac,96,80
    U,0x4212a0,0x4213a0,0x7eab8,96,80
    U,0x421300,0x421400,0x7e8ac,96,80
    U,0x421360,0x421460,0x7e8ac,96,80
    U,0x4213c0,0x4214c0,0x7e8ac,96,80
    U,0x421420,0x421520,0x803f4,1040,1024
    U,0x421830,0x421930,0x803f4,112,92
    U,0x4218a0,0x4219a0,0x803f4,1040,1024
    U,0x421cb0,0x421db0,0x803f4,112,92
    U,0x421d20,0x421e20,0x7e8ac,96,80
    U,0x421d80,0x421e80,0x7eab8,96,80
    U,0x421de0,0x421ee0,0x961bb,24,4
    U,0x421df8,0x421ef8,0x97b51,376,360
    U,0x421f70,0x422070,0x6e705,32,11
    U,0x421f90,0x422090,0x9642b,328,312
    U,0x4220d8,0x4221d8,0x96435,472,456
    U,0x4222b0,0x4223b0,0x96455,24,4
    U,0x4222c8,0x4223c8,0x6e705,32,9
    U,0x4222e8,0x4223e8,0x97b9d,24,4
    U,0x422300,0x422400,0x97aa1,288,268
    U,0x422420,0x422520,0x97e8b,24,4
    U,0x422438,0x422538,0xa4c29,24,4
    U,0x422450,0x422550,0x9ec37,88,72
    U,0x4224a8,0x4225a8,0x95a9f,48,28
    U,0x4224d8,0x4225d8,0x95a9f,48,28
    U,0x422508,0x422608,0x9ef85,56,40
    U,0x422540,0x422640,0x95a9f,48,28
    F,0x422570,0x422670,0x95943,32,16
    U,0x422590,0x422690,0xaf3ed,48,12
    U,0x4225c0,0x4226c0,0x9d865,72,56
    U,0x422608,0x422708,0x9d88b,1472,1456
    U,0x422bc8,0x422cc8,0x9d893,64,48
    U,0x422c08,0x422d08,0x986b3,40,20
    U,0x422c30,0x422d30,0x986e7,112,96
    U,0x422ca0,0x422da0,0x96559,104,88
    U,0x422d08,0x422e08,0xb1e05,360,342
    U,0x422e70,0x422f70,0x83c1b,48,26
    F,0x422ea0,0x422fa0,0x9594d,216,130
    U,0x422f78,0x423078,0x140f3,40,6
    U,0x422fa0,0x4230a0,0x9fe83,96,80
    F,0x423000,0x423100,0x8c255,176,130
    U,0x4230b0,0x4231b0,0x83c1b,24,1
    U,0x4230c8,0x4231c8,0x83c1b,40,20
    F,0x4230f0,0x4231f0,0x812b7,40,20
    U,0x423118,0x423218,0xb25ff,496,476
    U,0x423308,0x423408,0x9e865,88,72
    U,0x423360,0x423460,0x95a9f,48,28
    U,0x423390,0x423490,0x95a9f,48,28
    U,0x4233c0,0x4234c0,0xa4883,56,40
    U,0x4233f8,0x4234f8,0xa350b,112,96
    U,0x423468,0x423568,0xb0193,1048,1028
    U,0x423880,0x423980,0xaf9f7,40,20
    U,0x4238a8,0x4239a8,0x9d865,72,56
    U,0x4238f0,0x4239f0,0x9d88b,1472,1456
    U,0x423eb0,0x423fb0,0x9d893,64,48
    U,0x423ef0,0x423ff0,0x9ef85,56,40
    U,0x423f28,0x424028,0x95a9f,48,28
    U,0x423f58,0x424058,0x9fa4f,64,48
    U,0x423f98,0x424098,0x9f79d,32,9
    U,0x423fb8,0x4240b8,0x6e705,32,9
    U,0x423fd8,0x4240d8,0xb1fa5,144,128
    F,0x424068,0x424168,0x9e9a1,3200,512
    U,0x424ce8,0x424de8,0x803f4,2064,2048
    U,0x4254f8,0x4255f8,0x803f4,112,92
    F,0x425568,0x425668,0x95b35,32,16
    U,0x425588,0x425688,0x803f4,2064,2048
    U,0x425d98,0x425e98,0x803f4,112,92
    F,0x425e08,0x425f08,0x14d11,41448,1932
    

    打开 mqtt,然后再关闭 mqtt 之后的 heap info:

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    
    address: 0x40aae8
    size: 152856
    avail: 43120
    pool_start: 0x40aae8
    pool_end: 0x42fff0
    state,block_addr,user_addr,caller,blocksize,wanted_size
    U,0x40aae8,0x40abe8,0x1b695,4112,4096
    U,0x40baf8,0x40bbf8,0x1b6b5,40,20
    U,0x40bb20,0x40bc20,0x1b695,528,512
    U,0x40bd30,0x40be30,0x1b6b5,40,20
    U,0x40bd58,0x40be58,0x1b695,4112,4096
    U,0x40cd68,0x40ce68,0x1b6b5,40,20
    U,0x40cd90,0x40ce90,0x1b695,528,512
    U,0x40cfa0,0x40d0a0,0x1b6b5,40,20
    U,0x40cfc8,0x40d0c8,0x7eab8,96,80
    U,0x40d028,0x40d128,0x7e8ac,96,80
    U,0x40d088,0x40d188,0x28319,112,92
    U,0x40d0f8,0x40d1f8,0x28441,96,80
    U,0x40d158,0x40d258,0x7eab8,96,80
    U,0x40d1b8,0x40d2b8,0x7eab8,96,80
    U,0x40d218,0x40d318,0x28319,112,92
    U,0x40d288,0x40d388,0x28441,96,80
    U,0x40d2e8,0x40d3e8,0x7eab8,96,80
    U,0x40d348,0x40d448,0x7eab8,96,80
    U,0x40d3a8,0x40d4a8,0x28319,112,92
    U,0x40d418,0x40d518,0x28441,96,80
    U,0x40d478,0x40d578,0x7eab8,96,80
    U,0x40d4d8,0x40d5d8,0x7eab8,96,80
    U,0x40d538,0x40d638,0x803f4,112,92
    U,0x40d5a8,0x40d6a8,0xa4be5,56,36
    U,0x40d5e0,0x40d6e0,0x9fb53,48,28
    U,0x40d610,0x40d710,0xb22f3,760,744
    U,0x40d908,0x40da08,0x7f51c,1040,1024
    U,0x40dd18,0x40de18,0x7f51c,112,92
    U,0x40dd88,0x40de88,0x7fe1c,288,272
    U,0x40dea8,0x40dfa8,0x7fefc,3088,3072
    U,0x40eab8,0x40ebb8,0x7fefc,112,92
    U,0x40eb28,0x40ec28,0x15769,32,16
    U,0x40eb48,0x40ec48,0x15789,128,108
    U,0x40ebc8,0x40ecc8,0x157a9,136,114
    U,0x40ec50,0x40ed50,0x80808,120,100
    U,0x40ecc8,0x40edc8,0x803f4,1040,1024
    U,0x40f0d8,0x40f1d8,0x803f4,112,92
    U,0x40f148,0x40f248,0x7e8ac,96,80
    U,0x40f1a8,0x40f2a8,0x803f4,4112,4096
    U,0x4101b8,0x4102b8,0x803f4,112,92
    U,0x410228,0x410328,0x28441,96,80
    U,0x410288,0x410388,0x1405f,64,40
    U,0x4102c8,0x4103c8,0xa01ef,40,22
    U,0x4102f0,0x4103f0,0x80c7c,72,44
    U,0x410338,0x410438,0x83c1b,24,8
    U,0x410350,0x410450,0x83c1b,40,4
    U,0x410378,0x410478,0xa1b0d,64,32
    U,0x4103b8,0x4104b8,0x34f21,1040,1024
    U,0x4107c8,0x4108c8,0x9f79d,40,9
    U,0x4107f0,0x4108f0,0x9a079,192,172
    U,0x4108b0,0x4109b0,0x9bf95,40,22
    U,0x4108d8,0x4109d8,0x99f8f,224,208
    U,0x4109b8,0x410ab8,0x9c46f,64,48
    U,0x4109f8,0x410af8,0x9dfef,40,22
    U,0x410a20,0x410b20,0x6e705,32,9
    U,0x410a40,0x410b40,0xa01ef,56,22
    U,0x410a78,0x410b78,0x7eab8,96,80
    U,0x410ad8,0x410bd8,0x7eab8,96,80
    U,0x410b38,0x410c38,0x28319,224,208
    U,0x410c18,0x410d18,0x7eab8,96,80
    U,0x410c78,0x410d78,0x285a9,2064,2048
    U,0x411488,0x411588,0x285a9,112,92
    U,0x4114f8,0x4115f8,0x80808,1120,1104
    U,0x411958,0x411a58,0x803f4,4112,4096
    U,0x412968,0x412a68,0x803f4,112,92
    U,0x4129d8,0x412ad8,0x9d659,72,52
    U,0x412a20,0x412b20,0x7e8ac,96,80
    U,0x412a80,0x412b80,0x80808,1632,1616
    U,0x4130e0,0x4131e0,0x803f4,2064,2048
    U,0x4138f0,0x4139f0,0x803f4,112,92
    U,0x413960,0x413a60,0x80808,256,240
    U,0x413a60,0x413b60,0x803f4,1168,1152
    U,0x413ef0,0x413ff0,0xa46c5,952,936
    U,0x4142a8,0x4143a8,0xb1ff7,56,4
    U,0x4142e0,0x4143e0,0x80808,176,160
    U,0x414390,0x414490,0x803f4,4112,4096
    U,0x4153a0,0x4154a0,0x803f4,112,92
    U,0x415410,0x415510,0x7e8ac,96,80
    U,0x415470,0x415570,0x803f4,112,92
    U,0x4154e0,0x4155e0,0x80808,1296,1280
    U,0x4159f0,0x415af0,0x803f4,112,92
    U,0x415a60,0x415b60,0x7eab8,96,80
    U,0x415ac0,0x415bc0,0x7e8ac,96,80
    U,0x415b20,0x415c20,0x803f4,136,92
    U,0x415ba8,0x415ca8,0x1405f,56,40
    U,0x415be0,0x415ce0,0x1405f,56,40
    U,0x415c18,0x415d18,0x13ed5,24,5
    U,0x415c30,0x415d30,0x1405f,56,40
    U,0x415c68,0x415d68,0x13ed5,24,8
    U,0x415c80,0x415d80,0x1405f,56,40
    U,0x415cb8,0x415db8,0x13ed5,24,7
    U,0x415cd0,0x415dd0,0x1405f,56,40
    U,0x415d08,0x415e08,0x13ed5,24,2
    U,0x415d20,0x415e20,0x1405f,56,40
    U,0x415d58,0x415e58,0x13ed5,24,7
    U,0x415d70,0x415e70,0x1405f,56,40
    U,0x415da8,0x415ea8,0x13ed5,32,12
    U,0x415dc8,0x415ec8,0x1405f,56,40
    U,0x415e00,0x415f00,0x13ed5,24,8
    U,0x415e18,0x415f18,0x1405f,56,40
    U,0x415e50,0x415f50,0x13ed5,32,11
    U,0x415e70,0x415f70,0x13ed5,32,12
    U,0x415e90,0x415f90,0x1405f,56,40
    U,0x415ec8,0x415fc8,0x13ed5,32,13
    U,0x415ee8,0x415fe8,0x13ed5,56,33
    U,0x415f20,0x416020,0x1405f,56,40
    U,0x415f58,0x416058,0x13ed5,32,11
    U,0x415f78,0x416078,0x13ed5,24,8
    U,0x415f90,0x416090,0x1405f,56,40
    U,0x415fc8,0x4160c8,0x13ed5,24,7
    U,0x415fe0,0x4160e0,0x1405f,56,40
    U,0x416018,0x416118,0x13ed5,24,4
    U,0x416030,0x416130,0x1405f,56,40
    U,0x416068,0x416168,0x13ed5,24,2
    U,0x416080,0x416180,0x13ed5,32,12
    U,0x4160a0,0x4161a0,0x1405f,56,40
    U,0x4160d8,0x4161d8,0x13ed5,24,2
    U,0x4160f0,0x4161f0,0x13ed5,32,13
    U,0x416110,0x416210,0x1405f,56,40
    U,0x416148,0x416248,0x13ed5,24,4
    U,0x416160,0x416260,0x1405f,56,40
    U,0x416198,0x416298,0x13ed5,24,2
    U,0x4161b0,0x4162b0,0x13ed5,32,12
    U,0x4161d0,0x4162d0,0x1405f,56,40
    U,0x416208,0x416308,0x13ed5,24,2
    U,0x416220,0x416320,0x13ed5,32,13
    U,0x416240,0x416340,0x1405f,56,40
    U,0x416278,0x416378,0x13ed5,24,4
    U,0x416290,0x416390,0x1405f,56,40
    U,0x4162c8,0x4163c8,0x13ed5,24,2
    U,0x4162e0,0x4163e0,0x1405f,56,40
    U,0x416318,0x416418,0x13ed5,24,8
    U,0x416330,0x416430,0x1405f,56,40
    U,0x416368,0x416468,0x13ed5,32,11
    U,0x416388,0x416488,0x13ed5,32,12
    U,0x4163a8,0x4164a8,0x1405f,56,40
    U,0x4163e0,0x4164e0,0x13ed5,32,13
    U,0x416400,0x416500,0x13ed5,56,33
    U,0x416438,0x416538,0x1405f,56,40
    U,0x416470,0x416570,0x13ed5,32,11
    U,0x416490,0x416590,0x13ed5,24,8
    U,0x4164a8,0x4165a8,0x1405f,56,40
    U,0x4164e0,0x4165e0,0x13ed5,24,7
    U,0x4164f8,0x4165f8,0x1405f,56,40
    U,0x416530,0x416630,0x13ed5,32,12
    U,0x416550,0x416650,0x1405f,56,40
    U,0x416588,0x416688,0x13ed5,24,7
    U,0x4165a0,0x4166a0,0x1405f,56,40
    U,0x4165d8,0x4166d8,0x13ed5,24,4
    U,0x4165f0,0x4166f0,0x1405f,56,40
    U,0x416628,0x416728,0x13ed5,24,2
    U,0x416640,0x416740,0x13ed5,40,19
    U,0x416668,0x416768,0x1405f,56,40
    U,0x4166a0,0x4167a0,0x13ed5,24,2
    U,0x4166b8,0x4167b8,0x13ed5,32,12
    U,0x4166d8,0x4167d8,0x1405f,56,40
    U,0x416710,0x416810,0x13ed5,24,4
    U,0x416728,0x416828,0x1405f,56,40
    U,0x416760,0x416860,0x13ed5,24,2
    U,0x416778,0x416878,0x13ed5,40,19
    U,0x4167a0,0x4168a0,0x1405f,56,40
    U,0x4167d8,0x4168d8,0x13ed5,24,2
    U,0x4167f0,0x4168f0,0x13ed5,32,12
    U,0x416810,0x416910,0x1405f,56,40
    U,0x416848,0x416948,0x13ed5,24,4
    U,0x416860,0x416960,0x1405f,56,40
    U,0x416898,0x416998,0x13ed5,24,2
    U,0x4168b0,0x4169b0,0x1405f,56,40
    U,0x4168e8,0x4169e8,0x13ed5,24,8
    U,0x416900,0x416a00,0x1405f,56,40
    U,0x416938,0x416a38,0x13ed5,32,11
    U,0x416958,0x416a58,0x13ed5,32,12
    U,0x416978,0x416a78,0x1405f,56,40
    U,0x4169b0,0x416ab0,0x13ed5,32,13
    U,0x4169d0,0x416ad0,0x13ed5,56,33
    U,0x416a08,0x416b08,0x1405f,56,40
    U,0x416a40,0x416b40,0x13ed5,32,11
    U,0x416a60,0x416b60,0x13ed5,24,8
    U,0x416a78,0x416b78,0x1405f,56,40
    U,0x416ab0,0x416bb0,0x13ed5,24,7
    U,0x416ac8,0x416bc8,0x1405f,56,40
    U,0x416b00,0x416c00,0x13ed5,32,12
    U,0x416b20,0x416c20,0x1405f,56,40
    U,0x416b58,0x416c58,0x13ed5,24,7
    U,0x416b70,0x416c70,0x1405f,56,40
    U,0x416ba8,0x416ca8,0x13ed5,24,4
    U,0x416bc0,0x416cc0,0x1405f,56,40
    U,0x416bf8,0x416cf8,0x13ed5,24,2
    U,0x416c10,0x416d10,0x13ed5,40,19
    U,0x416c38,0x416d38,0x1405f,56,40
    U,0x416c70,0x416d70,0x13ed5,24,2
    U,0x416c88,0x416d88,0x13ed5,40,20
    U,0x416cb0,0x416db0,0x1405f,56,40
    U,0x416ce8,0x416de8,0x13ed5,24,4
    U,0x416d00,0x416e00,0x1405f,56,40
    U,0x416d38,0x416e38,0x13ed5,24,2
    U,0x416d50,0x416e50,0x13ed5,40,19
    U,0x416d78,0x416e78,0x1405f,56,40
    U,0x416db0,0x416eb0,0x13ed5,24,2
    U,0x416dc8,0x416ec8,0x13ed5,40,20
    U,0x416df0,0x416ef0,0x1405f,56,40
    U,0x416e28,0x416f28,0x13ed5,24,4
    U,0x416e40,0x416f40,0x1405f,56,40
    U,0x416e78,0x416f78,0x13ed5,24,2
    U,0x416e90,0x416f90,0x1405f,56,40
    U,0x416ec8,0x416fc8,0x13ed5,24,8
    U,0x416ee0,0x416fe0,0x1405f,56,40
    U,0x416f18,0x417018,0x13ed5,32,11
    U,0x416f38,0x417038,0x13ed5,32,12
    U,0x416f58,0x417058,0x1405f,56,40
    U,0x416f90,0x417090,0x13ed5,32,13
    U,0x416fb0,0x4170b0,0x13ed5,56,33
    U,0x416fe8,0x4170e8,0x1405f,56,40
    U,0x417020,0x417120,0x13ed5,32,11
    U,0x417040,0x417140,0x13ed5,32,13
    U,0x417060,0x417160,0x1405f,56,40
    U,0x417098,0x417198,0x13ed5,24,7
    U,0x4170b0,0x4171b0,0x1405f,56,40
    U,0x4170e8,0x4171e8,0x13ed5,32,12
    U,0x417108,0x417208,0x1405f,56,40
    U,0x417140,0x417240,0x13ed5,24,7
    U,0x417158,0x417258,0x1405f,56,40
    U,0x417190,0x417290,0x13ed5,24,4
    U,0x4171a8,0x4172a8,0x1405f,56,40
    U,0x4171e0,0x4172e0,0x13ed5,24,2
    U,0x4171f8,0x4172f8,0x13ed5,40,21
    U,0x417220,0x417320,0x1405f,56,40
    U,0x417258,0x417358,0x13ed5,24,2
    U,0x417270,0x417370,0x13ed5,40,22
    U,0x417298,0x417398,0x1405f,56,40
    U,0x4172d0,0x4173d0,0x13ed5,24,4
    U,0x4172e8,0x4173e8,0x1405f,56,40
    U,0x417320,0x417420,0x13ed5,24,2
    U,0x417338,0x417438,0x13ed5,40,21
    U,0x417360,0x417460,0x1405f,56,40
    U,0x417398,0x417498,0x13ed5,24,2
    U,0x4173b0,0x4174b0,0x13ed5,40,22
    U,0x4173d8,0x4174d8,0x1405f,56,40
    U,0x417410,0x417510,0x13ed5,24,4
    U,0x417428,0x417528,0x1405f,56,40
    U,0x417460,0x417560,0x13ed5,24,2
    U,0x417478,0x417578,0x1405f,56,40
    U,0x4174b0,0x4175b0,0x13ed5,24,8
    U,0x4174c8,0x4175c8,0x1405f,56,40
    U,0x417500,0x417600,0x13ed5,32,11
    U,0x417520,0x417620,0x13ed5,32,12
    U,0x417540,0x417640,0x1405f,56,40
    U,0x417578,0x417678,0x13ed5,32,13
    U,0x417598,0x417698,0x13ed5,56,33
    U,0x4175d0,0x4176d0,0x1405f,56,40
    U,0x417608,0x417708,0x13ed5,32,11
    U,0x417628,0x417728,0x13ed5,32,13
    U,0x417648,0x417748,0x1405f,56,40
    U,0x417680,0x417780,0x13ed5,24,7
    U,0x417698,0x417798,0x1405f,56,40
    U,0x4176d0,0x4177d0,0x13ed5,32,12
    U,0x4176f0,0x4177f0,0x1405f,56,40
    U,0x417728,0x417828,0x13ed5,24,7
    U,0x417740,0x417840,0x1405f,56,40
    U,0x417778,0x417878,0x13ed5,24,4
    U,0x417790,0x417890,0x1405f,56,40
    U,0x4177c8,0x4178c8,0x13ed5,24,2
    U,0x4177e0,0x4178e0,0x13ed5,40,21
    U,0x417808,0x417908,0x1405f,56,40
    U,0x417840,0x417940,0x13ed5,24,2
    U,0x417858,0x417958,0x13ed5,40,22
    U,0x417880,0x417980,0x1405f,56,40
    U,0x4178b8,0x4179b8,0x13ed5,24,4
    U,0x4178d0,0x4179d0,0x1405f,56,40
    U,0x417908,0x417a08,0x13ed5,24,2
    U,0x417920,0x417a20,0x13ed5,40,21
    U,0x417948,0x417a48,0x1405f,56,40
    U,0x417980,0x417a80,0x13ed5,24,2
    U,0x417998,0x417a98,0x13ed5,40,22
    U,0x4179c0,0x417ac0,0x1405f,56,40
    U,0x4179f8,0x417af8,0x13ed5,24,4
    U,0x417a10,0x417b10,0x1405f,56,40
    U,0x417a48,0x417b48,0x13ed5,24,8
    U,0x417a60,0x417b60,0x1405f,56,40
    U,0x417a98,0x417b98,0x1405f,56,40
    U,0x417ad0,0x417bd0,0x13ed5,24,8
    U,0x417ae8,0x417be8,0x1405f,56,40
    U,0x417b20,0x417c20,0x13ed5,32,9
    U,0x417b40,0x417c40,0x1405f,56,40
    U,0x417b78,0x417c78,0x13ed5,32,9
    U,0x417b98,0x417c98,0x1405f,56,40
    U,0x417bd0,0x417cd0,0x13ed5,24,6
    U,0x417be8,0x417ce8,0x1405f,56,40
    U,0x417c20,0x417d20,0x1405f,56,40
    U,0x417c58,0x417d58,0x13ed5,24,8
    U,0x417c70,0x417d70,0x1405f,56,40
    U,0x417ca8,0x417da8,0x13ed5,32,9
    U,0x417cc8,0x417dc8,0x1405f,56,40
    U,0x417d00,0x417e00,0x13ed5,32,9
    U,0x417d20,0x417e20,0x1405f,56,40
    U,0x417d58,0x417e58,0x13ed5,24,6
    U,0x417d70,0x417e70,0x1405f,56,40
    U,0x417da8,0x417ea8,0x1405f,56,40
    U,0x417de0,0x417ee0,0x13ed5,24,8
    U,0x417df8,0x417ef8,0x1405f,56,40
    U,0x417e30,0x417f30,0x13ed5,32,9
    U,0x417e50,0x417f50,0x1405f,56,40
    U,0x417e88,0x417f88,0x13ed5,32,9
    U,0x417ea8,0x417fa8,0x1405f,56,40
    U,0x417ee0,0x417fe0,0x13ed5,24,6
    U,0x417ef8,0x417ff8,0x1405f,56,40
    U,0x417f30,0x418030,0x1405f,56,40
    U,0x417f68,0x418068,0x13ed5,24,8
    U,0x417f80,0x418080,0x1405f,56,40
    U,0x417fb8,0x4180b8,0x13ed5,32,9
    U,0x417fd8,0x4180d8,0x1405f,56,40
    U,0x418010,0x418110,0x13ed5,32,9
    U,0x418030,0x418130,0x1405f,56,40
    U,0x418068,0x418168,0x13ed5,24,6
    U,0x418080,0x418180,0x1405f,56,40
    U,0x4180b8,0x4181b8,0x1405f,56,40
    U,0x4180f0,0x4181f0,0x13ed5,24,8
    U,0x418108,0x418208,0x1405f,56,40
    U,0x418140,0x418240,0x13ed5,32,9
    U,0x418160,0x418260,0x1405f,56,40
    U,0x418198,0x418298,0x13ed5,32,9
    F,0x4181b8,0x4182b8,0x812b7,80,20
    U,0x418208,0x418308,0x1405f,56,40
    U,0x418240,0x418340,0x13ed5,32,10
    U,0x418260,0x418360,0x1405f,56,40
    U,0x418298,0x418398,0x13ed5,24,2
    U,0x4182b0,0x4183b0,0x1405f,56,40
    U,0x4182e8,0x4183e8,0x13ed5,32,9
    U,0x418308,0x418408,0x1405f,56,40
    U,0x418340,0x418440,0x13ed5,24,5
    U,0x418358,0x418458,0x1405f,56,40
    U,0x418390,0x418490,0x13ed5,24,8
    U,0x4183a8,0x4184a8,0x1405f,56,40
    U,0x4183e0,0x4184e0,0x13ed5,24,5
    U,0x4183f8,0x4184f8,0x1405f,56,40
    U,0x418430,0x418530,0x13ed5,24,5
    U,0x418448,0x418548,0x13ed5,24,1
    U,0x418460,0x418560,0x1405f,56,40
    U,0x418498,0x418598,0x13ed5,24,7
    U,0x4184b0,0x4185b0,0x1405f,56,40
    U,0x4184e8,0x4185e8,0x13ed5,24,2
    U,0x418500,0x418600,0x1405f,56,40
    U,0x418538,0x418638,0x13ed5,32,9
    U,0x418558,0x418658,0x1405f,56,40
    U,0x418590,0x418690,0x13ed5,24,5
    U,0x4185a8,0x4186a8,0x1405f,56,40
    U,0x4185e0,0x4186e0,0x13ed5,24,8
    U,0x4185f8,0x4186f8,0x1405f,56,40
    U,0x418630,0x418730,0x13ed5,24,5
    U,0x418648,0x418748,0x1405f,56,40
    U,0x418680,0x418780,0x13ed5,24,5
    U,0x418698,0x418798,0x13ed5,24,1
    U,0x4186b0,0x4187b0,0x1405f,56,40
    U,0x4186e8,0x4187e8,0x13ed5,24,7
    U,0x418700,0x418800,0x1405f,56,40
    U,0x418738,0x418838,0x13ed5,24,2
    U,0x418750,0x418850,0x1405f,56,40
    U,0x418788,0x418888,0x13ed5,32,9
    U,0x4187a8,0x4188a8,0x1405f,56,40
    U,0x4187e0,0x4188e0,0x13ed5,24,5
    U,0x4187f8,0x4188f8,0x1405f,56,40
    U,0x418830,0x418930,0x13ed5,24,8
    U,0x418848,0x418948,0x1405f,56,40
    U,0x418880,0x418980,0x13ed5,24,5
    U,0x418898,0x418998,0x1405f,56,40
    U,0x4188d0,0x4189d0,0x13ed5,24,5
    U,0x4188e8,0x4189e8,0x13ed5,24,1
    U,0x418900,0x418a00,0x1405f,56,40
    U,0x418938,0x418a38,0x13ed5,24,7
    U,0x418950,0x418a50,0x3dc13,2720,2704
    U,0x4193f0,0x4194f0,0x803f4,3088,3072
    U,0x41a000,0x41a100,0x803f4,3088,3072
    U,0x41ac10,0x41ad10,0x80808,896,880
    U,0x41af90,0x41b090,0x803f4,1040,1024
    U,0x41b3a0,0x41b4a0,0x803f4,12304,12288
    U,0x41e3b0,0x41e4b0,0x803f4,112,92
    U,0x41e420,0x41e520,0x80808,1296,1280
    U,0x41e930,0x41ea30,0x803f4,5136,5120
    U,0x41fd40,0x41fe40,0x803f4,112,92
    U,0x41fdb0,0x41feb0,0x803f4,4112,4096
    U,0x420dc0,0x420ec0,0x803f4,112,92
    F,0x420e30,0x420f30,0x956db,64,36
    U,0x420e70,0x420f70,0x42d97,40,20
    U,0x420e98,0x420f98,0x7eab8,96,80
    U,0x420ef8,0x420ff8,0x42d97,40,20
    U,0x420f20,0x421020,0x7eab8,96,80
    U,0x420f80,0x421080,0x42d97,40,20
    U,0x420fa8,0x4210a8,0x7eab8,96,80
    U,0x421008,0x421108,0x42d97,40,20
    U,0x421030,0x421130,0x7eab8,96,80
    U,0x421090,0x421190,0x42d97,40,20
    U,0x4210b8,0x4211b8,0x7eab8,96,80
    U,0x421118,0x421218,0x42d97,40,20
    U,0x421140,0x421240,0x7eab8,96,80
    U,0x4211a0,0x4212a0,0x7eab8,96,80
    U,0x421200,0x421300,0x80c7c,64,44
    U,0x421240,0x421340,0x7e8ac,96,80
    U,0x4212a0,0x4213a0,0x7eab8,96,80
    U,0x421300,0x421400,0x7e8ac,96,80
    U,0x421360,0x421460,0x7e8ac,96,80
    U,0x4213c0,0x4214c0,0x7e8ac,96,80
    U,0x421420,0x421520,0x803f4,1040,1024
    U,0x421830,0x421930,0x803f4,112,92
    U,0x4218a0,0x4219a0,0x803f4,1040,1024
    U,0x421cb0,0x421db0,0x803f4,112,92
    U,0x421d20,0x421e20,0x7e8ac,96,80
    U,0x421d80,0x421e80,0x7eab8,96,80
    U,0x421de0,0x421ee0,0x961bb,24,4
    U,0x421df8,0x421ef8,0x97b51,376,360
    U,0x421f70,0x422070,0x6e705,32,11
    U,0x421f90,0x422090,0x9642b,328,312
    U,0x4220d8,0x4221d8,0x96435,472,456
    U,0x4222b0,0x4223b0,0x96455,24,4
    U,0x4222c8,0x4223c8,0x6e705,32,9
    U,0x4222e8,0x4223e8,0x97b9d,24,4
    U,0x422300,0x422400,0x97aa1,288,268
    U,0x422420,0x422520,0x97e8b,24,4
    U,0x422438,0x422538,0xa4c29,24,4
    U,0x422450,0x422550,0x9ec37,88,72
    U,0x4224a8,0x4225a8,0x95a9f,48,28
    U,0x4224d8,0x4225d8,0x95a9f,48,28
    U,0x422508,0x422608,0x9ef85,56,40
    U,0x422540,0x422640,0x95a9f,48,28
    F,0x422570,0x422670,0x363c5,32,8
    U,0x422590,0x422690,0xaf3ed,48,12
    U,0x4225c0,0x4226c0,0x9d865,72,56
    U,0x422608,0x422708,0x9d88b,1472,1456
    U,0x422bc8,0x422cc8,0x9d893,64,48
    U,0x422c08,0x422d08,0x986b3,40,20
    U,0x422c30,0x422d30,0x986e7,112,96
    U,0x422ca0,0x422da0,0x96559,104,88
    U,0x422d08,0x422e08,0xb1e05,360,342
    U,0x422e70,0x422f70,0x83c1b,48,26
    F,0x422ea0,0x422fa0,0x9594d,256,88
    U,0x422fa0,0x4230a0,0x9fe83,96,80
    F,0x423000,0x423100,0x7e8ac,176,80
    U,0x4230b0,0x4231b0,0x83c1b,24,1
    U,0x4230c8,0x4231c8,0x83c1b,40,20
    F,0x4230f0,0x4231f0,0x812b7,40,20
    U,0x423118,0x423218,0xb25ff,496,476
    U,0x423308,0x423408,0x9e865,88,72
    U,0x423360,0x423460,0x95a9f,48,28
    U,0x423390,0x423490,0x95a9f,48,28
    U,0x4233c0,0x4234c0,0xa4883,56,40
    U,0x4233f8,0x4234f8,0xa350b,112,96
    U,0x423468,0x423568,0xb0193,1048,1028
    U,0x423880,0x423980,0xaf9f7,40,20
    U,0x4238a8,0x4239a8,0x9d865,72,56
    U,0x4238f0,0x4239f0,0x9d88b,1472,1456
    U,0x423eb0,0x423fb0,0x9d893,64,48
    U,0x423ef0,0x423ff0,0x9ef85,56,40
    U,0x423f28,0x424028,0x95a9f,48,28
    U,0x423f58,0x424058,0x9fa4f,64,48
    U,0x423f98,0x424098,0x9f79d,32,9
    U,0x423fb8,0x4240b8,0x6e705,32,9
    U,0x423fd8,0x4240d8,0xb1fa5,144,128
    F,0x424068,0x424168,0x9e9a1,3200,512
    U,0x424ce8,0x424de8,0x803f4,2064,2048
    U,0x4254f8,0x4255f8,0x803f4,112,92
    F,0x425568,0x425668,0x9e083,32,12
    U,0x425588,0x425688,0x803f4,2064,2048
    U,0x425d98,0x425e98,0x803f4,112,92
    U,0x425e08,0x425f08,0x140f3,32,6
    U,0x425e28,0x425f28,0x803f4,2064,2048
    U,0x426638,0x426738,0x803f4,112,92
    F,0x4266a8,0x4267a8,0x14d11,39240,1932
    

    对比之下,比较明显地增加了几条新 heap 使用信息

    1
    2
    3
    
    U,0x425e08,0x425f08,0x140f3,32,6
    U,0x425e28,0x425f28,0x803f4,2064,2048
    U,0x426638,0x426738,0x803f4,112,92
    

    再用 address2line 工具定位这几块内存是哪里申请的

    1
    2
    3
    4
    5
    6
    7
    8
    
    toolchain/gcc-arm-none-eabi-5_4-2016q3/bin 
    ❯ ./arm-none-eabi-addr2line -e ~/FC41D/beken_freertos_sdk_release-SDK_3.0.21/out/beken7231_bsp.elf -f 0x140f3 0x803f4 0x803f4
    cJSON_strdup
    /home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/demos/common/json/cJSON.c:67
    rtos_create_thread
    /home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/os/FreeRTOSv9.0.0/rtos_pub.c:98
    rtos_create_thread
    /home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/os/FreeRTOSv9.0.0/rtos_pub.c:98
    

    /home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/os/FreeRTOSv9.0.0/rtos_pub.c:98 对应的是创建线程的函数 rtos_create_thread

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    int ali_iot_close(custom_func_ch_id_e func_id, void *hdl)
    {
        ali_iot_mqtt_client_t *mqtt_client = hdl;
    
        if (mqtt_client == NULL)
        {
            return -1;
        }
        rtos_lock_mutex(&mqtt_client->lock);
    
        rtos_delete_thread(mqtt_client->task);
        MQTTDisconnect(&mqtt_client->client);
    	NetworkDisconnect(&mqtt_client->network);
        mqtt_client->ev_cb(mqtt_client, QL_MQTT_CLOSE, (QL_MQTT_OK << 16)|QL_MQTT_CLOSE_BY_DISCONNECT, NULL, (void *)mqtt_client->func_id);
        if(mqtt_client->sign_mqtt)
        {
            free(mqtt_client->sign_mqtt);
        }
        if(mqtt_client->sub_topic[0])
        {
            free(mqtt_client->sub_topic[0]);
        }
        if(mqtt_client->sub_topic[1])
        {
            free(mqtt_client->sub_topic[1]);
        }
        rtos_unlock_mutex(&mqtt_client->lock);
    
        rtos_deinit_mutex(&mqtt_client->lock);
        free(mqtt_client);
    
        return 0;
    }
    

    分析代码之后,找到原因是关闭mqtt的时候,没有正确删除线程导致的内存泄漏。 rtos_delete_thread(mqtt_client->task); 传参不对,修改为 rtos_delete_thread(&mqtt_client->task);之后正常。

    内存泄漏的判断方法:

    1. 功能打开关闭之后,对比前后的 heap info 信息,看看有哪些新增加的内存分配信息,按照这个线索去排查。
    2. 挂机压测一段时间之后,打印 heap info 信息,按照 caller 出现的次数排序,出现次数较多的前几个 caller,或者内存申请较多的caller,是该怀疑存在内存泄漏的对象。

    heap 内存写越界案例

    free 的时候检测到内存块被破坏

    1
    2
    3
    4
    5
    
    mem corrupt,block:0x422ef8, blocksize:24, xWantedSize:4, caller:0x34747
    dump block:
    00000000:  00 00 00 00 18 00 00 00  ........
    00000008:  04 00 00 00 47 47 03 00  ....GG..
    00000010:  48 54 54 50 2F 31 2E 30  HTTP/1.0
    

    调用者申请了4字节内存空间,分配的内存块大小是24字节,减去头部16字节,后面填充了4字节的0xfd,从dump的内存数据来看,填充的数据都被覆盖完了, 通过 caller:0x34747 查找代码位置

    1
    2
    3
    4
    
    FC41D/beken_freertos_sdk_release-SDK_3.0.21 on  Iotbranch [!?⇡] 
    ❯ ./toolchain/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-addr2line -e Release/Debug/beken7231_bsp.elf  -f 0x34747
    fs_open_custom
    /home/x/FC41D/beken_freertos_sdk_release-SDK_3.0.21/beken378/func/lwip_intf/lwip-2.0.2/src/apps/httpd/custom_fsdata.c:239
    

    对应代码:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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
    
    int fs_open_custom(struct fs_file *file, const char *name)
    {
        char *wifi_data="{\"aps\":[{\"ssid\":\"123\"},{\"ssid\":\"test234\"}]}";
        int file_data_len = 0;
        
         /* this example only provides one file */
         if (!strcmp(name, "/wifilist.html"))
         {
             /* initialize fs_file correctly */
             memset(file, 0, sizeof(struct fs_file));
             file_data_len = strlen((char *)CUSTOM_FSDATA_WIFILIST_HTML_HEADER) + strlen(wifi_data) +2;
             file->pextension = malloc(sizeof(file_data_len));
             if (file->pextension != NULL)
             {
                memset(file->pextension, 0, file_data_len);
                file_data_len = snprintf(file->pextension, file_data_len - 1, "%s%s", (char *)CUSTOM_FSDATA_WIFILIST_HTML_HEADER, wifi_data);
            
                file->data = (const char *)file->pextension;
                file->len = file_data_len; /* don't send the trailing 0 */
                file->index = file->len;
                /* allow persisteng connections */
                file->flags = FS_FILE_FLAGS_HEADER_INCLUDED;
                return 1;
             }
         }
         else if(!strcmp(name, "/index.html"))
         {
             char *sta_state_data = NULL;
             uint32 uart_band = 9600;
             uint8 ssid[33] = {0};
             uint8 psk[64] = {0};
    
             int apon = 0;
             char *ap_state_data = NULL;
    
             if (custom_fsdata_sta_state() == 1)
             {
                 sta_state_data = CUSTOM_FSDATA_STA_CONNECTED;
             }
             else
             {
                 sta_state_data = CUSTOM_FSDATA_STA_DISCONNECTED;
             }
    
             custom_sw_ap_cfg_get(apssid, appass, &apon);
    
             if (apon == 1)
             {
                 ap_state_data = "Up";
             }
             else
             {
                 ap_state_data = "Down";
             }
    
             custom_config_uart_braud_get(&uart_band);
    
             custom_sta_cfg_get(ssid, psk);
             /* initialize fs_file correctly */
             memset(file, 0, sizeof(struct fs_file));
             file_data_len = strlen((char *)CUSTOM_FSDATA_INDEX_HTML_HEADER) + strlen((char *)CUSTOM_FSDATA_INDEX_HTML_FILE_FMT) + 10 /* for uart band */ + strlen((char *)ssid) + strlen(ap_state_data) + strlen(sta_state_data) + strlen((char *)apssid) + 1 /* \0 */;
             file->pextension = malloc(sizeof(file_data_len));
             if (file->pextension != NULL)
             {
                memset(file->pextension, 0, file_data_len);
                file_data_len = snprintf(file->pextension, file_data_len - 1, (char *)CUSTOM_FSDATA_INDEX_HTML_FILE_FMT, (char *)CUSTOM_FSDATA_INDEX_HTML_HEADER, (char *)ssid, sta_state_data, (char *)apssid, ap_state_data, uart_band);
            
                file->data = (const char *)file->pextension;
                file->len = file_data_len; /* don't send the trailing 0 */
                file->index = file->len;
                /* allow persisteng connections */
                file->flags = FS_FILE_FLAGS_HEADER_INCLUDED;
                return 1;
             }
         }
         return 0;
    }
    

    file->pextension = malloc(sizeof(file_data_len)); 传的参数传错了,sizeof(file_data_len) 是4字节,实际需要申请 file_data_len 字节,导致后面内存写越界了。



沪ICP备19023445号-2号
友情链接