[esp32] Use DRAM_ATTR for format strings in IRAM log override

ESP-IDF places log_format_text.c in IRAM/DRAM via linker fragment
(noflash) when CONFIG_LOG_IN_IRAM=y. Our override is in a different
compilation unit so string literals would default to flash. In
constrained environments where flash cache is disabled, reading
flash-resident format strings would fault.

Move all format string constants to DRAM_ATTR to match ESP-IDF's
own behavior.
This commit is contained in:
J. Nick Koston
2026-03-13 17:03:14 -10:00
parent 3a491722b2
commit 99e0dcf563
+12 -5
View File
@@ -110,9 +110,16 @@ int HOT esp_idf_log_vprintf_(const char *format, va_list args) { // NOLINT
static void IRAM_ATTR __attribute__((noinline)) esp_log_format_early_(esp_log_msg_t *message) {
// ESP-IDF levels: NONE=0 ERROR=1 WARN=2 INFO=3 DEBUG=4 VERBOSE=5
// Color digits: E=1(red) W=3(yellow) I=2(green) D=6(cyan) V=7(gray)
// DRAM_ATTR required since this function is in IRAM and can't access flash constants
// DRAM_ATTR required: this function is IRAM_ATTR and may be called from constrained
// environments where flash cache is disabled. All string constants must be in DRAM.
// ESP-IDF's own log_format_text.c achieves this via linker fragment (noflash), but
// our override is in a different compilation unit so we must use DRAM_ATTR explicitly.
static DRAM_ATTR const char color_digit[] = {'\0', '1', '3', '2', '6', '7'};
static DRAM_ATTR const char lvl[] = {'\0', 'E', 'W', 'I', 'D', 'V'};
static DRAM_ATTR const char fmt_header[] = "\033[0;3%cm[%c][%s:000]: ";
static DRAM_ATTR const char fmt_reset_nl[] = "\033[0m\n";
static DRAM_ATTR const char fmt_nl[] = "\n";
static DRAM_ATTR const char tag_fallback[] = "esp-idf";
uint8_t level = message->config.opts.log_level;
#if CONFIG_LIBC_NEWLIB
if (!message->config.opts.constrained_env) {
@@ -120,14 +127,14 @@ static void IRAM_ATTR __attribute__((noinline)) esp_log_format_early_(esp_log_ms
}
#endif
if (level > 0 && level < sizeof(lvl)) {
esp_log_printf(message->config, "\033[0;3%cm[%c][%s:000]: ", color_digit[level], lvl[level],
message->tag ? message->tag : "esp-idf");
esp_log_printf(message->config, fmt_header, color_digit[level], lvl[level],
message->tag ? message->tag : tag_fallback);
}
esp_log_vprintf(message->config, message->format, message->args);
if (level > 0 && level < sizeof(lvl)) {
esp_log_printf(message->config, "\033[0m\n");
esp_log_printf(message->config, fmt_reset_nl);
} else {
esp_log_printf(message->config, "\n");
esp_log_printf(message->config, fmt_nl);
}
#if CONFIG_LIBC_NEWLIB
if (!message->config.opts.constrained_env) {