Consejos de FreeRTOS (dos): cómo diagnosticar pérdidas de memoria

Este blog se utiliza para explicar cómo diagnosticar dónde se produce una pérdida de memoria en FreeRTOS.


1. Pasos para diagnosticar pérdidas de memoria

Si sospecha que hay una pérdida de memoria, el primer paso es averiguar qué parte del programa está perdiendo memoria. Utilice xPortGetFreeHeapSize()o heap_caps_get_free_size()para realizar un seguimiento del uso de la memoria en el ciclo de vida de la aplicación. Intente reducir el alcance de la fuga a una sola función o una serie de funciones, porque en estas funciones o una serie de funciones, la memoria disponible siempre disminuirá. Una vez que haya determinado el segmento de código que cree que se está filtrando a través de la API anterior, debe hacer lo siguiente para diagnosticar la pérdida de memoria:

  • Por make menuconifgproyecto abre el menú de configuración, ingrese Component settings-> Heap Memory Debugging-> Heap tracingy seleccione StandaloneOpciones (Ver CONFIG_HEAP_TRACING_DEST ).

  • Al principio del programa llama a la heap_trace_init_standalone()función para registrar un búfer que se puede utilizar para registrar un rastro de memoria.

  • Funciones de llamada heap_trace_start()en todo el sistema de grabación de inicio malloc / free. Puede llamar a esta función antes del segmento de código donde sospecha una pérdida de memoria.

  • Una vez finalizado el código sospechoso, debe llamar a heap_trace_stop()una función para detener la pista.

  • Llame al heap_trace_dump()resultado de la función para volcar el seguimiento de la pila.

2. Ejemplos de uso

Los siguientes son ejemplos de uso relacionado (asumiendo que sospecha que do_something_you_suspect_is_leaking()este código tiene fugas de memoria):

#include "esp_heap_trace.h"

#define NUM_RECORDS 100
static heap_trace_record_t trace_record[NUM_RECORDS]; // This buffer must be in internal RAM

...

void app_main()
{
    
    
    ...
    ESP_ERROR_CHECK( heap_trace_init_standalone(trace_record, NUM_RECORDS) );
    ...
}

void some_function()
{
    
    
    ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );

    do_something_you_suspect_is_leaking();

    ESP_ERROR_CHECK( heap_trace_stop() );
    heap_trace_dump();
    ...
}

El registro de salida del seguimiento del montón es el siguiente:

2 allocations trace (100 entry buffer)
32 bytes (@ 0x3ffaf214) allocated CPU 0 ccount 0x2e9b7384 caller 0x400d276d:0x400d27c1
0x400d276d: leak_some_memory at /path/to/idf/examples/get-started/blink/main/./blink.c:27

0x400d27c1: blink_task at /path/to/idf/examples/get-started/blink/main/./blink.c:52

8 bytes (@ 0x3ffaf804) allocated CPU 0 ccount 0x2e9b79c0 caller 0x400d2776:0x400d27c1
0x400d2776: leak_some_memory at /path/to/idf/examples/get-started/blink/main/./blink.c:29

0x400d27c1: blink_task at /path/to/idf/examples/get-started/blink/main/./blink.c:52

40 bytes 'leaked' in trace (2 allocations)
total allocations 2 total frees 0

Nota: La salida de ejemplo anterior usa IDF Monitor para decodificar automáticamente la dirección de la PC en su archivo fuente y número de línea. )

Luego puede analizar el seguimiento de la pila del registro de salida, la primera línea 2 allocations trace (100 entry buffer)indica que el búfer tiene (en comparación con su tamaño total) un número de entradas de asignación.

Además, en el HEAP_TRACE_LEAKSmodo, para cada asignación de memoria rastreada que aún no se haya liberado, imprima una línea:

  • XX bytes Es el número de bytes asignados

  • @ 0x...De malloc / callocla dirección de retorno del montón.

  • CPU x Es la CPU (0 o 1) que se está ejecutando durante la asignación.

  • ccount 0x...Es el valor del registro CCOUNT (recuento de ciclos de CPU) cuando se asigna al modo. La CPU 0 es diferente de la CPU 1.

  • caller 0x...Dado a malloc()/ free()la llamada de la pila de llamadas, la lista de direcciones como una PC. Puede decodificarlos en archivos fuente y números de línea, como se muestra arriba.

Puede make menuconfigconfigurarse para abrir el elemento de menú Heap Memory Debugging> - Enable heap tracing> - Heap tracing stack depthconfigurado para rastrear las entradas grabadas profundidad de pila de llamadas para cada una de las siguientes. Cada asignación puede registrar hasta 10 marcos de pila (el valor predeterminado es 2). Cada fotograma de pila de cada heap_trace_record_tuso de memoria adicional registrado por 8 bytes.

Finalmente, 40 bytes leaked in trace (2 allocations)imprima el número total de bytes "filtrados" (bytes que han sido asignados pero liberados cuando el rastreo no se está ejecutando) y utilícelo para indicar el número total de asignaciones.

Si el tamaño del búfer de seguimiento no es lo suficientemente grande para acomodar todas las asignaciones que ocurren, se imprime una advertencia. Si ve esta advertencia, considere reducir el tiempo de seguimiento o aumentar el número de registros en el búfer de seguimiento.

Supongo que te gusta

Origin blog.csdn.net/zztiger123/article/details/106275613
Recomendado
Clasificación