Skip to content

Commit

Permalink
Merge branch 'coredump_save_all_regions_v5.3' into 'release/v5.3'
Browse files Browse the repository at this point in the history
Save .bss, .data and .heap sections in to the coredump (v5.3)

See merge request espressif/esp-idf!30438
  • Loading branch information
jack0c committed Jul 26, 2024
2 parents 3e826dd + 0f96e51 commit 5325cac
Show file tree
Hide file tree
Showing 16 changed files with 399 additions and 77 deletions.
15 changes: 14 additions & 1 deletion components/espcoredump/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ menu "Core dump"
depends on ESP_COREDUMP_DATA_FORMAT_ELF
endchoice

config ESP_COREDUMP_CAPTURE_DRAM
bool "Include whole .bss and .data sections and heap data into core dump file"
default n
#TODO: Heap walker api is not ready for the esp32c5 (IDF-9641)
depends on ESP_COREDUMP_DATA_FORMAT_ELF && !IDF_TARGET_ESP32C5
help
Storing these sections can help with easier debugging and troubleshooting.
However, additional storage space will be required in the core dump partition.
At least 128KB should be reserved, but the actual amount required may vary based
on the application's DRAM usage.
Note that sections located in external RAM will not be stored.

config ESP_COREDUMP_CHECK_BOOT
bool "Check core dump data integrity on boot"
default y
Expand Down Expand Up @@ -112,7 +124,8 @@ menu "Core dump"
help
Size of the memory to be reserved for core dump stack. If 0 core dump process will run on
the stack of crashed task/ISR, otherwise special stack will be allocated.
To ensure that core dump itself will not overflow task/ISR stack set this to the value above 800.
To ensure that core dump itself will not overflow task/ISR stack set this to the value around 1300-1800
depending on the chosen checksum calculation method. SHA256 method needs more stack space than CRC32.
NOTE: It eats DRAM.

config ESP_COREDUMP_SUMMARY_STACKDUMP_SIZE
Expand Down
22 changes: 19 additions & 3 deletions components/espcoredump/include_core_dump/esp_core_dump_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,25 @@ extern "C" {
* One can use these definitions to retrieve the start address and/or the size
* of a specific region using the functions below.
*/

typedef enum {
COREDUMP_MEMORY_DRAM,
COREDUMP_MEMORY_IRAM,
#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
COREDUMP_MEMORY_DRAM_BSS,
COREDUMP_MEMORY_DRAM_DATA,
#if CONFIG_IDF_TARGET_ESP32P4
COREDUMP_MEMORY_DRAM_BSS_HIGH,
COREDUMP_MEMORY_DRAM_DATA_HIGH,
#endif
#else
COREDUMP_MEMORY_DRAM,
#endif
#if SOC_RTC_MEM_SUPPORTED
COREDUMP_MEMORY_RTC,
COREDUMP_MEMORY_RTC_FAST,
#endif
COREDUMP_MEMORY_MAX,
COREDUMP_MEMORY_START = COREDUMP_MEMORY_DRAM
COREDUMP_MEMORY_START = COREDUMP_MEMORY_IRAM
} coredump_region_t;

/**
Expand Down Expand Up @@ -126,6 +136,12 @@ esp_err_t esp_core_dump_write_data(core_dump_write_data_t *wr_data, void *data,
*/
esp_err_t esp_core_dump_write_end(core_dump_write_data_t *wr_data);

/**
* @brief Retrieve the stack information which will be used from the coredump module itself.
* It will show the whole stack boundaries in case the stack is shared with the crashed task.
*/
void esp_core_dump_get_own_stack_info(uint32_t *addr, uint32_t *size);

/**
* @brief Stores the core dump in either binary or ELF format.
*/
Expand Down Expand Up @@ -157,7 +173,7 @@ static inline core_dump_task_handle_t esp_core_dump_get_current_task_handle(void
* @brief Get the length, in bytes, of a given memory location. Padding is
* taken into account in this calculation.
*
* @param start Start address of the momery location.
* @param start Start address of the memory location.
* @param end End address of the memory location.
*
* @return Size of the memory location, multiple of sizeof(uint32_t).
Expand Down
100 changes: 64 additions & 36 deletions components/espcoredump/src/core_dump_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ const static char TAG[] __attribute__((unused)) = "esp_core_dump_common";
/**
* @brief Memory regions to dump, defined at compile time.
*/
#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
#if !CONFIG_IDF_TARGET_ESP32P4
extern int _bss_start;
extern int _bss_end;
extern int _data_start;
extern int _data_end;
#else
extern int _bss_start_low;
extern int _bss_end_low;
extern int _data_start_low;
extern int _data_end_low;
extern int _bss_start_high;
extern int _bss_end_high;
extern int _data_start_high;
extern int _data_end_high;
#endif
#endif

/* Regions for the user defined variable locations */
extern int _coredump_dram_start;
extern int _coredump_dram_end;
extern int _coredump_iram_start;
Expand Down Expand Up @@ -160,6 +179,7 @@ FORCE_INLINE_ATTR void esp_core_dump_setup_stack(void)
FORCE_INLINE_ATTR void esp_core_dump_report_stack_usage(void)
{
}

#endif // CONFIG_ESP_COREDUMP_STACK_SIZE > 0

static void* s_exc_frame = NULL;
Expand Down Expand Up @@ -254,56 +274,64 @@ uint32_t esp_core_dump_get_user_ram_segments(void)
return total_sz;
}

uint32_t esp_core_dump_get_user_ram_size(void)
{
uint32_t total_sz = 0;

total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_dram_end, &_coredump_dram_start);
static const struct {
int *start;
int *end;
} s_memory_sections[COREDUMP_MEMORY_MAX] = {
[COREDUMP_MEMORY_IRAM] = { &_coredump_iram_start, &_coredump_iram_end },
#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
#if !CONFIG_IDF_TARGET_ESP32P4
[COREDUMP_MEMORY_DRAM_BSS] = { &_bss_start, &_bss_end },
[COREDUMP_MEMORY_DRAM_DATA] = { &_data_start, &_data_end },
#else
[COREDUMP_MEMORY_DRAM_BSS] = { &_bss_start_low, &_bss_end_low },
[COREDUMP_MEMORY_DRAM_DATA] = { &_data_start_low, &_data_end_low },
[COREDUMP_MEMORY_DRAM_BSS_HIGH] = { &_bss_start_high, &_bss_end_high },
[COREDUMP_MEMORY_DRAM_DATA_HIGH] = { &_data_start_high, &_data_end_high },
#endif
#else
[COREDUMP_MEMORY_DRAM] = { &_coredump_dram_start, &_coredump_dram_end },
#endif
#if SOC_RTC_MEM_SUPPORTED
total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_rtc_end, &_coredump_rtc_start);
total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_rtc_fast_end, &_coredump_rtc_fast_start);
[COREDUMP_MEMORY_RTC] = { &_coredump_rtc_start, &_coredump_rtc_end },
[COREDUMP_MEMORY_RTC_FAST] = { &_coredump_rtc_fast_start, &_coredump_rtc_fast_end },
#endif
total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_iram_end, &_coredump_iram_start);

return total_sz;
}
};

int esp_core_dump_get_user_ram_info(coredump_region_t region, uint32_t *start)
{
int total_sz = -1;

ESP_COREDUMP_DEBUG_ASSERT(start != NULL);

switch (region) {
case COREDUMP_MEMORY_DRAM:
*start = (uint32_t)&_coredump_dram_start;
total_sz = (uint8_t *)&_coredump_dram_end - (uint8_t *)&_coredump_dram_start;
break;

case COREDUMP_MEMORY_IRAM:
*start = (uint32_t)&_coredump_iram_start;
total_sz = (uint8_t *)&_coredump_iram_end - (uint8_t *)&_coredump_iram_start;
break;

#if SOC_RTC_MEM_SUPPORTED
case COREDUMP_MEMORY_RTC:
*start = (uint32_t)&_coredump_rtc_start;
total_sz = (uint8_t *)&_coredump_rtc_end - (uint8_t *)&_coredump_rtc_start;
break;

case COREDUMP_MEMORY_RTC_FAST:
*start = (uint32_t)&_coredump_rtc_fast_start;
total_sz = (uint8_t *)&_coredump_rtc_fast_end - (uint8_t *)&_coredump_rtc_fast_start;
break;
#endif

default:
break;
if (region >= COREDUMP_MEMORY_START && region < COREDUMP_MEMORY_MAX) {
total_sz = (uint8_t *)s_memory_sections[region].end - (uint8_t *)s_memory_sections[region].start;
*start = (uint32_t)s_memory_sections[region].start;
}

return total_sz;
}

#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM
void esp_core_dump_get_own_stack_info(uint32_t *addr, uint32_t *size)
{
#if CONFIG_ESP_COREDUMP_STACK_SIZE > 0
/* Custom stack reserved for the coredump */
*addr = (uint32_t)s_coredump_stack;
*size = sizeof(s_coredump_stack);
#else
/* Shared stack with the crashed task */
core_dump_task_handle_t handle = esp_core_dump_get_current_task_handle();
TaskSnapshot_t rtos_snapshot = { 0 };
vTaskGetSnapshot(handle, &rtos_snapshot);
StaticTask_t *current = (StaticTask_t *)handle;
*addr = (uint32_t)current->pxDummy6; //pxStack
*size = (uint32_t)rtos_snapshot.pxTopOfStack - (uint32_t)current->pxDummy6; /* free */
#endif
}

#endif /* CONFIG_ESP_COREDUMP_CAPTURE_DRAM */

inline bool esp_core_dump_tcb_addr_is_sane(uint32_t addr)
{
return esp_core_dump_mem_seg_is_sane(addr, esp_core_dump_get_tcb_len());
Expand Down
Loading

0 comments on commit 5325cac

Please sign in to comment.