This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Memory Manager Diagnostics doesn't work

Hi,

We are working with SDK v14.1 and are trying to debug some memory issues by enabling MEM_MANAGER_ENABLE_DIAGNOSTICS.

In memory_manager.c in function print_block_info() the macro NRF_LOG_BYTES_DEBUG is used to print the status of the memory blocks. This macro however isn't defined anywhere, seems like the log module doesn't implement it.

We tried to replace this macro by various variants of NRF_LOG_DEBUG, but it seems (also according to its definition), that this macro only allows to print strings that are defined during compile time (const). Any run time-defined strings in functions can't be printed, since their pointer becomes invalid after the function returns.

We solved the problem by changing the print_buffer array in function print_block_info() to static, to keep the pointer valid. Since the print_block_info() is called 7 times after another for all types of memory block size, print_buffer had to be changed to a two dimensional array.

This however consumes 7*80=560 bytes of RAM, essentially wasting memory, so we were wondering if there was an easier solution to this issue.

Thanks, Carl

Parents
  • Just in case anyone else comes across this issue, here's a very quick and dirty fix to the print_block_info() function:

    void print_block_info(uint32_t block_cat, uint32_t * p_mem_in_use)
    {
    #define PRINT_COLUMN_WIDTH      13
    #define PRINT_BUFFER_SIZE       80
    #define ASCII_VALUE_FOR_SPACE   32
    
    char           print_buffer[PRINT_BUFFER_SIZE];
    const uint32_t total_count   = (m_block_start[block_cat] + m_block_count[block_cat]);
    uint32_t       in_use        = 0;
    uint32_t       num_of_blocks = 0;
    uint32_t       index         = m_block_start[block_cat];
    uint32_t       column_number;
    
    // No statistic provided in case block category is not included.
    if (m_block_count[block_cat] != 0)
    {
        memset(print_buffer, ASCII_VALUE_FOR_SPACE, PRINT_BUFFER_SIZE);
    
        for (; index < total_count; index++)
        {
            if (is_block_free(index) == false)
            {
                num_of_blocks++;
                in_use += m_block_size[block_cat];
            }
        }
    
        column_number = 0;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %s",
                 m_block_desc_str[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_block_size[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_block_count[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 num_of_blocks);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_min_size[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_max_size[block_cat]);
    
        column_number++;
        const uint32_t column_end = (column_number * PRINT_COLUMN_WIDTH);
    
        for (int j = 0; j < column_end; j ++)
        {
            if (print_buffer[j] == 0)
            {
                print_buffer[j] = 0x20;
            }
        }
        snprintf(&print_buffer[column_end], 2, "|");
    
        NRF_LOG_DEBUG("%s", print_buffer);
    
        (*p_mem_in_use) += in_use;
    }
    }
    
Reply
  • Just in case anyone else comes across this issue, here's a very quick and dirty fix to the print_block_info() function:

    void print_block_info(uint32_t block_cat, uint32_t * p_mem_in_use)
    {
    #define PRINT_COLUMN_WIDTH      13
    #define PRINT_BUFFER_SIZE       80
    #define ASCII_VALUE_FOR_SPACE   32
    
    char           print_buffer[PRINT_BUFFER_SIZE];
    const uint32_t total_count   = (m_block_start[block_cat] + m_block_count[block_cat]);
    uint32_t       in_use        = 0;
    uint32_t       num_of_blocks = 0;
    uint32_t       index         = m_block_start[block_cat];
    uint32_t       column_number;
    
    // No statistic provided in case block category is not included.
    if (m_block_count[block_cat] != 0)
    {
        memset(print_buffer, ASCII_VALUE_FOR_SPACE, PRINT_BUFFER_SIZE);
    
        for (; index < total_count; index++)
        {
            if (is_block_free(index) == false)
            {
                num_of_blocks++;
                in_use += m_block_size[block_cat];
            }
        }
    
        column_number = 0;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %s",
                 m_block_desc_str[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_block_size[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_block_count[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 num_of_blocks);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_min_size[block_cat]);
    
        column_number++;
        snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
                 PRINT_COLUMN_WIDTH,
                 "| %d",
                 m_max_size[block_cat]);
    
        column_number++;
        const uint32_t column_end = (column_number * PRINT_COLUMN_WIDTH);
    
        for (int j = 0; j < column_end; j ++)
        {
            if (print_buffer[j] == 0)
            {
                print_buffer[j] = 0x20;
            }
        }
        snprintf(&print_buffer[column_end], 2, "|");
    
        NRF_LOG_DEBUG("%s", print_buffer);
    
        (*p_mem_in_use) += in_use;
    }
    }
    
Children
Related