Merge branch 'fix/coredump_test_uart_data_missing_v5.2' into 'release/v5.2'

Fix missing coredump uart data in tests (v5.2)

See merge request espressif/esp-idf!36713
This commit is contained in:
Alexey Gerenkov 2025-03-04 00:12:14 +08:00
commit 12901ff20b
2 changed files with 61 additions and 16 deletions

View File

@ -1,6 +1,7 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import re
from typing import Any
from typing import List
from typing import Optional
from typing import Union
@ -89,9 +90,43 @@ def get_default_backtrace(config: str) -> List[str]:
return [config, 'app_main', 'main_task', 'vPortTaskWrapper']
def expect_coredump_flash_write_logs(dut: PanicTestDut, config: str) -> None:
dut.expect_exact('Save core dump to flash...')
if 'extram_stack' in config:
dut.expect_exact('Backing up stack @')
dut.expect_exact('Restoring stack')
dut.expect_exact('Core dump has been saved to flash.')
dut.expect(dut.REBOOT)
def expect_coredump_uart_write_logs(dut: PanicTestDut, check_cpu_reset: Optional[bool] = True) -> Any:
# ================= CORE DUMP START =================
# B8AAAMAEgAGAAAAXAEAAAAAAABkAAAA
# ...
# ================= CORE DUMP END =================
# Coredump checksum='9730d7ff'
# Rebooting...
# ..
# rst:0xc (SW_CPU_RESET),boot:
# Read all uart logs until the end of the reset reason
uart_str = dut.expect(',boot:', return_what_before_match=True).decode('utf-8', errors='ignore')
coredump_base64 = uart_str.split(dut.COREDUMP_UART_START)[1].split(dut.COREDUMP_UART_END)[0].strip()
uart_str = uart_str.split(dut.COREDUMP_UART_END)[1]
assert re.search(dut.COREDUMP_CHECKSUM, uart_str)
assert re.search(dut.REBOOT, uart_str)
if check_cpu_reset:
assert re.search(dut.CPU_RESET, uart_str)
return coredump_base64
def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[List[str]] = None, check_cpu_reset: Optional[bool] = True,
expected_coredump: Optional[List[Union[str, re.Pattern]]] = None) -> None:
if 'gdbstub' in config:
if 'coredump' in config:
uart_str = dut.expect(dut.COREDUMP_CHECKSUM, return_what_before_match=True).decode('utf-8')
coredump_base64 = uart_str.split(dut.COREDUMP_UART_START)[1].split(dut.COREDUMP_UART_END)[0].strip()
dut.process_coredump_uart(coredump_base64, expected_coredump)
dut.expect_exact('Entering gdb stub now.')
dut.start_gdb()
frames = dut.gdb_backtrace()
@ -105,13 +140,13 @@ def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[Lis
expected_coredump = None
if 'uart' in config:
dut.process_coredump_uart(expected_coredump)
coredump_base64 = expect_coredump_uart_write_logs(dut, check_cpu_reset)
dut.process_coredump_uart(coredump_base64, expected_coredump)
check_cpu_reset = False # CPU reset is already checked in expect_coredump_uart_write_logs
elif 'flash' in config:
dut.process_coredump_flash(expected_coredump)
elif 'panic' in config:
pass
dut.expect('Rebooting...')
dut.expect(dut.REBOOT)
if check_cpu_reset:
dut.expect_cpu_reset()

View File

@ -1,14 +1,23 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
import re
import subprocess
import sys
from typing import Any, Dict, List, Optional, TextIO, Union
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import TextIO
from typing import Union
import pexpect
from panic_utils import NoGdbProcessError, attach_logger, quote_string, sha256, verify_valid_gdb_subprocess
from panic_utils import attach_logger
from panic_utils import NoGdbProcessError
from panic_utils import quote_string
from panic_utils import sha256
from panic_utils import verify_valid_gdb_subprocess
from pygdbmi.gdbcontroller import GdbController
from pytest_embedded_idf.app import IdfApp
from pytest_embedded_idf.dut import IdfDut
@ -19,8 +28,11 @@ class PanicTestDut(IdfDut):
BOOT_CMD_ADDR = 0x9000
BOOT_CMD_SIZE = 0x1000
DEFAULT_EXPECT_TIMEOUT = 10
COREDUMP_UART_START = '================= CORE DUMP START ================='
COREDUMP_UART_END = '================= CORE DUMP END ================='
COREDUMP_UART_START = r'================= CORE DUMP START ================='
COREDUMP_UART_END = r'================= CORE DUMP END ================='
COREDUMP_CHECKSUM = r"Coredump checksum='([a-fA-F0-9]+)'"
REBOOT = r'.*Rebooting\.\.\.'
CPU_RESET = r'.*rst:.*(RTC_SW_CPU_RST|SW_CPU_RESET|SW_CPU)\b'
app: IdfApp
serial: IdfSerial
@ -95,7 +107,7 @@ class PanicTestDut(IdfDut):
def expect_cpu_reset(self) -> None:
# no digital system reset for panic handling restarts (see IDF-7255)
self.expect(r'.*rst:.*(RTC_SW_CPU_RST|SW_CPU_RESET|SW_CPU)')
self.expect(self.CPU_RESET)
def expect_elf_sha256(self) -> None:
"""Expect method for ELF SHA256 line"""
@ -145,11 +157,9 @@ class PanicTestDut(IdfDut):
self.coredump_output.flush()
self.coredump_output.seek(0)
def process_coredump_uart(self, expected: Optional[List[Union[str, re.Pattern]]] = None) -> None:
"""Extract the core dump from UART output of the test, run espcoredump on it"""
self.expect(self.COREDUMP_UART_START)
res = self.expect('(.+)' + self.COREDUMP_UART_END)
coredump_base64 = res.group(1).decode('utf8')
def process_coredump_uart(
self, coredump_base64: Any, expected: Optional[List[Union[str, re.Pattern]]] = None,
) -> None:
with open(os.path.join(self.logdir, 'coredump_data.b64'), 'w') as coredump_file:
logging.info('Writing UART base64 core dump to %s', coredump_file.name)
coredump_file.write(coredump_base64)