feat(coredump): add coredump_extram attribute

Closes https://github.com/espressif/esp-idf/issues/15429
This commit is contained in:
Erhan Kurubas
2026-01-28 22:29:22 +01:00
parent 526891e08f
commit 5ba3e9df98
8 changed files with 77 additions and 2 deletions
+6
View File
@@ -137,8 +137,11 @@ extern "C" {
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
// Forces bss variable into external memory. "
#define EXT_RAM_BSS_ATTR _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__)
// Forces data into external memory BSS and maps it to coredump
#define COREDUMP_EXTRAM_ATTR _SECTION_ATTR_IMPL(".ext_ram.coredump", __COUNTER__)
#else
#define EXT_RAM_BSS_ATTR
#define COREDUMP_EXTRAM_ATTR
#endif
// Forces data into noinit section to avoid initialization after restart.
@@ -147,9 +150,12 @@ extern "C" {
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
// Forces data into external memory noinit section to avoid initialization after restart.
#define EXT_RAM_NOINIT_ATTR _SECTION_ATTR_IMPL(".ext_ram_noinit", __COUNTER__)
// Forces data into external memory noinit section and maps it to coredump
#define COREDUMP_EXTRAM_NOINIT_ATTR _SECTION_ATTR_IMPL(".ext_ram_noinit.coredump", __COUNTER__)
#else
// Place in internal noinit section
#define EXT_RAM_NOINIT_ATTR __NOINIT_ATTR
#define COREDUMP_EXTRAM_NOINIT_ATTR
#endif
// Forces code into DRAM instead of flash and map it to coredump
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -38,6 +38,12 @@ typedef enum {
COREDUMP_MEMORY_RTC_FAST,
#endif
COREDUMP_MEMORY_NOINIT,
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
COREDUMP_MEMORY_EXTRAM,
#endif
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
COREDUMP_MEMORY_EXTRAM_NOINIT,
#endif
COREDUMP_MEMORY_MAX,
COREDUMP_MEMORY_START = COREDUMP_MEMORY_IRAM
} coredump_region_t;
+13 -1
View File
@@ -25,6 +25,14 @@ entries:
entries:
.noinit.coredump+
[sections:extram_coredump]
entries:
.ext_ram.coredump+
[sections:extram_noinit_coredump]
entries:
.ext_ram_noinit.coredump+
[scheme:coredump_default]
entries:
dram_coredump -> dram0_data
@@ -33,6 +41,8 @@ entries:
rtc_noinit_coredump -> rtc_noinit
noinit_coredump -> noinit
iram_coredump -> iram0_data
extram_coredump -> extern_ram
extram_noinit_coredump -> extram_noinit
[mapping:coredump_default]
archive: *
@@ -43,7 +53,9 @@ entries:
rtc_noinit_coredump -> rtc_noinit SURROUND(coredump_rtc_noinit),
noinit_coredump -> noinit SURROUND(coredump_noinit),
dram_coredump -> dram0_data SURROUND(coredump_dram),
iram_coredump -> iram0_data SURROUND(coredump_iram)
iram_coredump -> iram0_data SURROUND(coredump_iram),
extram_coredump -> extern_ram SURROUND(coredump_extram),
extram_noinit_coredump -> extram_noinit SURROUND(coredump_extram_noinit)
[mapping:espcoredump]
archive: libespcoredump.a
@@ -57,6 +57,14 @@ extern int _coredump_rtc_noinit_end;
extern int _coredump_noinit_start;
extern int _coredump_noinit_end;
#endif
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
extern int _coredump_extram_start;
extern int _coredump_extram_end;
#endif
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
extern int _coredump_extram_noinit_start;
extern int _coredump_extram_noinit_end;
#endif
static void* s_exc_frame = NULL;
static uint32_t s_coredump_sp = 0;
@@ -271,6 +279,12 @@ static const struct {
#else
[COREDUMP_MEMORY_NOINIT] = { &_coredump_noinit_start, &_coredump_noinit_end },
#endif
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
[COREDUMP_MEMORY_EXTRAM] = { &_coredump_extram_start, &_coredump_extram_end },
#endif
#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
[COREDUMP_MEMORY_EXTRAM_NOINIT] = { &_coredump_extram_noinit_start, &_coredump_extram_noinit_end },
#endif
};
int esp_core_dump_get_user_ram_info(coredump_region_t region, uint32_t *start)
@@ -87,6 +87,10 @@ void test_panic_print_backtrace(void);
void test_panic_halt(void);
#endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT */
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
void test_panic_extram_attr(void);
#endif
#ifdef __cplusplus
}
#endif
@@ -218,5 +218,9 @@ void app_main(void)
#endif
#endif
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
HANDLE_TEST(test_name, test_panic_extram_attr);
#endif
die("Unknown test name");
}
@@ -430,6 +430,16 @@ void test_capture_dram(void)
}
#endif
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
COREDUMP_EXTRAM_ATTR uint32_t g_extram_bss_var;
COREDUMP_EXTRAM_NOINIT_ATTR uint32_t g_extram_noinit_var;
void test_panic_extram_attr(void)
{
g_extram_bss_var = 123456;
g_extram_noinit_var = 789012;
assert(0);
}
#endif
#if CONFIG_ESP_SYSTEM_USE_FRAME_POINTER
@@ -284,6 +284,25 @@ def test_panic_extram_stack(dut: PanicTestDut, config: str) -> None:
common_test(dut, config, expected_backtrace=None, expected_coredump=[coredump_pattern])
@pytest.mark.psram
@idf_parametrize('config, target', [('coredump_flash_extram_attr_esp32', 'esp32')], indirect=['config', 'target'])
def test_panic_extram_attr(dut: PanicTestDut, config: str) -> None:
dut.run_test_func('test_panic_extram_attr')
regex_pattern = rb'assert failed:[\s\w()]*?\s[.\w/]*\.(?:c|cpp|h|hpp):\d.*$'
dut.expect(re.compile(regex_pattern, re.MULTILINE))
dut.expect_backtrace()
dut.expect_elf_sha256()
dut.expect_none(['Guru Meditation', 'Re-entered core dump'])
expect_coredump_flash_write_logs(dut, config)
core_elf_file = dut.process_coredump_flash()
dut.start_gdb_for_coredump(core_elf_file)
assert dut.gdb_data_eval_expr('g_extram_bss_var') == '123456'
assert dut.gdb_data_eval_expr('g_extram_noinit_var') == '789012'
@pytest.mark.generic
@idf_parametrize('config, target', CONFIGS, indirect=['config', 'target'])
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration')