Merge branch 'tools/added_chip_rev_field_into_coredump_header' into 'master'

coredump: added the chip_rev field into the coredump header

See merge request espressif/esp-idf!21315
This commit is contained in:
Roland Dobai
2023-07-26 21:03:18 +08:00
5 changed files with 65 additions and 33 deletions

View File

@@ -66,9 +66,9 @@ extern "C" {
/* legacy bin coredumps (before IDF v4.1) has version set to 1 */ /* legacy bin coredumps (before IDF v4.1) has version set to 1 */
#define COREDUMP_VERSION_BIN_LEGACY COREDUMP_VERSION_MAKE(COREDUMP_VERSION_BIN, 1) // -> 0x0001 #define COREDUMP_VERSION_BIN_LEGACY COREDUMP_VERSION_MAKE(COREDUMP_VERSION_BIN, 1) // -> 0x0001
#define COREDUMP_VERSION_BIN_CURRENT COREDUMP_VERSION_MAKE(COREDUMP_VERSION_BIN, 2) // -> 0x0002 #define COREDUMP_VERSION_BIN_CURRENT COREDUMP_VERSION_MAKE(COREDUMP_VERSION_BIN, 3) // -> 0x0003
#define COREDUMP_VERSION_ELF_CRC32 COREDUMP_VERSION_MAKE(COREDUMP_VERSION_ELF, 0) // -> 0x0100 #define COREDUMP_VERSION_ELF_CRC32 COREDUMP_VERSION_MAKE(COREDUMP_VERSION_ELF, 2) // -> 0x0102
#define COREDUMP_VERSION_ELF_SHA256 COREDUMP_VERSION_MAKE(COREDUMP_VERSION_ELF, 1) // -> 0x0101 #define COREDUMP_VERSION_ELF_SHA256 COREDUMP_VERSION_MAKE(COREDUMP_VERSION_ELF, 3) // -> 0x0103
#define COREDUMP_CURR_TASK_MARKER 0xDEADBEEF #define COREDUMP_CURR_TASK_MARKER 0xDEADBEEF
#define COREDUMP_CURR_TASK_NOT_FOUND -1 #define COREDUMP_CURR_TASK_NOT_FOUND -1
@@ -143,6 +143,7 @@ typedef struct _core_dump_header_t
uint32_t tasks_num; /*!< Number of tasks */ uint32_t tasks_num; /*!< Number of tasks */
uint32_t tcb_sz; /*!< Size of a TCB, in bytes */ uint32_t tcb_sz; /*!< Size of a TCB, in bytes */
uint32_t mem_segs_num; /*!< Number of memory segments */ uint32_t mem_segs_num; /*!< Number of memory segments */
uint32_t chip_rev; /*!< Chip revision */
} core_dump_header_t; } core_dump_header_t;
/** /**

View File

@@ -10,6 +10,7 @@
#include "core_dump_binary.h" #include "core_dump_binary.h"
#include "esp_core_dump_port.h" #include "esp_core_dump_port.h"
#include "esp_core_dump_common.h" #include "esp_core_dump_common.h"
#include "hal/efuse_hal.h"
#if CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN #if CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN
@@ -175,6 +176,7 @@ esp_err_t esp_core_dump_write_binary(core_dump_write_config_t *write_cfg)
hdr.data_len = data_len; hdr.data_len = data_len;
hdr.version = COREDUMP_VERSION_BIN_CURRENT; hdr.version = COREDUMP_VERSION_BIN_CURRENT;
hdr.tcb_sz = tcb_sz; hdr.tcb_sz = tcb_sz;
hdr.chip_rev = efuse_hal_chip_revision();
err = write_cfg->write(write_cfg->priv, &hdr, sizeof(core_dump_header_t)); err = write_cfg->write(write_cfg->priv, &hdr, sizeof(core_dump_header_t));
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_COREDUMP_LOGE("Failed to write core dump header error=%d!", err); ESP_COREDUMP_LOGE("Failed to write core dump header error=%d!", err);

View File

@@ -13,6 +13,7 @@
#include "esp_core_dump_port.h" #include "esp_core_dump_port.h"
#include "esp_core_dump_port_impl.h" #include "esp_core_dump_port_impl.h"
#include "esp_core_dump_common.h" #include "esp_core_dump_common.h"
#include "hal/efuse_hal.h"
#ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF #ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
#include "esp_app_desc.h" #include "esp_app_desc.h"
@@ -608,6 +609,7 @@ esp_err_t esp_core_dump_write_elf(core_dump_write_config_t *write_cfg)
dump_hdr.tasks_num = 0; // unused in ELF format dump_hdr.tasks_num = 0; // unused in ELF format
dump_hdr.tcb_sz = 0; // unused in ELF format dump_hdr.tcb_sz = 0; // unused in ELF format
dump_hdr.mem_segs_num = 0; // unused in ELF format dump_hdr.mem_segs_num = 0; // unused in ELF format
dump_hdr.chip_rev = efuse_hal_chip_revision();
err = write_cfg->write(write_cfg->priv, err = write_cfg->write(write_cfg->priv,
(void*)&dump_hdr, (void*)&dump_hdr,
sizeof(core_dump_header_t)); sizeof(core_dump_header_t));

View File

@@ -3,8 +3,6 @@ components/efuse/efuse_table_gen.py
components/efuse/test_efuse_host/efuse_tests.py components/efuse/test_efuse_host/efuse_tests.py
components/esp_local_ctrl/python/esp_local_ctrl_pb2.py components/esp_local_ctrl/python/esp_local_ctrl_pb2.py
components/esp_netif/test_apps/component_ut_test.py components/esp_netif/test_apps/component_ut_test.py
components/espcoredump/corefile/gdb.py
components/espcoredump/test/test_espcoredump.py
components/lwip/weekend_test/net_suite_test.py components/lwip/weekend_test/net_suite_test.py
components/mbedtls/esp_crt_bundle/gen_crt_bundle.py components/mbedtls/esp_crt_bundle/gen_crt_bundle.py
components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/test_gen_crt_bundle.py components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/test_gen_crt_bundle.py

View File

@@ -12,7 +12,7 @@ import time
from base64 import b64decode from base64 import b64decode
from textwrap import indent from textwrap import indent
from threading import Thread from threading import Thread
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional, Union
from click import INT from click import INT
from click.core import Context from click.core import Context
@@ -70,6 +70,18 @@ def get_openocd_arguments(target: str) -> str:
return str(OPENOCD_TAGET_CONFIG.get(target, default_args)) return str(OPENOCD_TAGET_CONFIG.get(target, default_args))
def chip_rev_to_int(chip_rev: Optional[str]) -> Union[int, None]:
# The chip rev will be derived from the elf file if none are returned.
# The chip rev must be supplied for coredump files generated with idf versions less than 5.1 in order to load
# rom elf file.
if not chip_rev or not all(c.isdigit() or c == '.' for c in chip_rev):
return None
if '.' not in chip_rev:
chip_rev += '.0'
major, minor = map(int, chip_rev.split('.'))
return major * 100 + minor
def action_extensions(base_actions: Dict, project_path: str) -> Dict: def action_extensions(base_actions: Dict, project_path: str) -> Dict:
OPENOCD_OUT_FILE = 'openocd_out.txt' OPENOCD_OUT_FILE = 'openocd_out.txt'
GDBGUI_OUT_FILE = 'gdbgui_out.txt' GDBGUI_OUT_FILE = 'gdbgui_out.txt'
@@ -137,6 +149,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
args: PropertyDict, args: PropertyDict,
gdb_timeout_sec: int = None, gdb_timeout_sec: int = None,
core: str = None, core: str = None,
chip_rev: str = None,
save_core: str = None) -> CoreDump: save_core: str = None) -> CoreDump:
ensure_build_directory(args, ctx.info_name) ensure_build_directory(args, ctx.info_name)
@@ -146,8 +159,20 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
coredump_to_flash = coredump_to_flash_config.rstrip().endswith('y') if coredump_to_flash_config else False coredump_to_flash = coredump_to_flash_config.rstrip().endswith('y') if coredump_to_flash_config else False
prog = os.path.join(project_desc['build_dir'], project_desc['app_elf']) prog = os.path.join(project_desc['build_dir'], project_desc['app_elf'])
args.port = args.port or get_default_serial_port()
espcoredump_kwargs = dict()
espcoredump_kwargs['baud'] = args.baud
espcoredump_kwargs['gdb_timeout_sec'] = gdb_timeout_sec
espcoredump_kwargs['chip_rev'] = chip_rev_to_int(chip_rev)
# for reproducible builds
extra_gdbinit_file = project_desc.get('debug_prefix_map_gdbinit', None)
if extra_gdbinit_file:
espcoredump_kwargs['extra_gdbinit_file'] = extra_gdbinit_file
espcoredump_kwargs: Dict[str, Any] = dict()
core_format = None core_format = None
if core: if core:
@@ -164,16 +189,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
sys.exit(1) sys.exit(1)
espcoredump_kwargs['port'] = args.port espcoredump_kwargs['port'] = args.port
espcoredump_kwargs['baud'] = args.baud espcoredump_kwargs['parttable_off'] = get_sdkconfig_value(project_desc['config_file'],
espcoredump_kwargs['gdb_timeout_sec'] = gdb_timeout_sec 'CONFIG_PARTITION_TABLE_OFFSET')
# for reproducible builds
extra_gdbinit_file = project_desc.get('debug_prefix_map_gdbinit', None)
if extra_gdbinit_file:
espcoredump_kwargs['extra_gdbinit_file'] = extra_gdbinit_file
espcoredump_kwargs['parttable_off'] = get_sdkconfig_value(project_desc['config_file'], 'CONFIG_PARTITION_TABLE_OFFSET')
if core_format: if core_format:
espcoredump_kwargs['core_format'] = core_format espcoredump_kwargs['core_format'] = core_format
@@ -245,7 +262,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
base_ident = ' ' base_ident = ' '
rom_elfs_dir = os.getenv('ESP_ROM_ELF_DIR') rom_elfs_dir = os.getenv('ESP_ROM_ELF_DIR')
if not rom_elfs_dir: if not rom_elfs_dir:
raise FatalError('ESP_ROM_ELF_DIR environment variable is not defined. Please try to run IDF "install" and "export" scripts.') raise FatalError(
'ESP_ROM_ELF_DIR environment variable is not defined. Please try to run IDF "install" and "export" scripts.')
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), ESP_ROM_INFO_FILE), 'r') as f: with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), ESP_ROM_INFO_FILE), 'r') as f:
roms = json.load(f) roms = json.load(f)
if target not in roms: if target not in roms:
@@ -382,8 +400,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
# use default value if commands not defined in the environment nor command line # use default value if commands not defined in the environment nor command line
target = project_desc['target'] target = project_desc['target']
openocd_arguments = get_openocd_arguments(target) openocd_arguments = get_openocd_arguments(target)
print('Note: OpenOCD cfg not found (via env variable OPENOCD_COMMANDS nor as a --openocd-commands argument)\n' print(
'OpenOCD arguments default to: "{}"'.format(openocd_arguments)) 'Note: OpenOCD cfg not found (via env variable OPENOCD_COMMANDS nor as a --openocd-commands argument)\n'
'OpenOCD arguments default to: "{}"'.format(openocd_arguments))
# script directory is taken from the environment by OpenOCD, update only if command line arguments to override # script directory is taken from the environment by OpenOCD, update only if command line arguments to override
if openocd_scripts is not None: if openocd_scripts is not None:
openocd_arguments += ' -s {}'.format(openocd_scripts) openocd_arguments += ' -s {}'.format(openocd_scripts)
@@ -469,8 +488,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
if debug_targets: if debug_targets:
# Register the meta cleanup callback -> called on FatalError # Register the meta cleanup callback -> called on FatalError
ctx.meta['cleanup'] = debug_cleanup ctx.meta['cleanup'] = debug_cleanup
move_to_front('gdbgui') # possibly 2nd move_to_front('gdbgui') # possibly 2nd
move_to_front('openocd') # always 1st move_to_front('openocd') # always 1st
# followed by "monitor", "gdb" or "gdbtui" in any order # followed by "monitor", "gdb" or "gdbtui" in any order
post_action = ctx.invoke(ctx.command.get_command(ctx, 'post_debug')) post_action = ctx.invoke(ctx.command.get_command(ctx, 'post_debug'))
@@ -478,7 +497,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
post_action.action_args['block'] = 0 post_action.action_args['block'] = 0
else: else:
post_action.action_args['block'] = 1 post_action.action_args['block'] = 1
tasks.append(post_action) # always last tasks.append(post_action) # always last
if any([task.name == 'openocd' for task in tasks]): if any([task.name == 'openocd' for task in tasks]):
for task in tasks: for task in tasks:
if task.name in ('gdb', 'gdbgui', 'gdbtui'): if task.name in ('gdb', 'gdbgui', 'gdbtui'):
@@ -490,11 +509,12 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
""" """
gdb(action, ctx, args, False, 1, gdbinit, require_openocd) gdb(action, ctx, args, False, 1, gdbinit, require_openocd)
def gdb(action: str, ctx: Context, args: PropertyDict, batch: bool, gdb_tui: Optional[int], gdbinit: Optional[str], require_openocd: bool) -> None: def gdb(action: str, ctx: Context, args: PropertyDict, batch: bool, gdb_tui: Optional[int], gdbinit: Optional[str],
require_openocd: bool) -> None:
""" """
Synchronous GDB target Synchronous GDB target
""" """
watch_openocd = Thread(target=_check_openocd_errors, args=(fail_if_openocd_failed, action, ctx, )) watch_openocd = Thread(target=_check_openocd_errors, args=(fail_if_openocd_failed, action, ctx,))
watch_openocd.start() watch_openocd.start()
processes['threads_to_join'].append(watch_openocd) processes['threads_to_join'].append(watch_openocd)
project_desc = get_project_desc(args, ctx) project_desc = get_project_desc(args, ctx)
@@ -527,8 +547,10 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
args: PropertyDict, args: PropertyDict,
gdb_timeout_sec: int, gdb_timeout_sec: int,
core: str = None, core: str = None,
chip_rev: str = None,
save_core: str = None) -> None: save_core: str = None) -> None:
espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, gdb_timeout_sec=gdb_timeout_sec, core=core, espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, gdb_timeout_sec=gdb_timeout_sec, core=core,
chip_rev=chip_rev,
save_core=save_core) save_core=save_core)
espcoredump.info_corefile() espcoredump.info_corefile()
@@ -537,8 +559,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
ctx: Context, ctx: Context,
args: PropertyDict, args: PropertyDict,
core: str = None, core: str = None,
chip_rev: str = None,
save_core: str = None) -> None: save_core: str = None) -> None:
espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, core=core, save_core=save_core) espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, core=core, chip_rev=chip_rev, save_core=save_core)
espcoredump.dbg_corefile() espcoredump.dbg_corefile()
@@ -547,6 +570,12 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
'names': ['--core', '-c'], 'names': ['--core', '-c'],
'help': 'Path to core dump file (if skipped core dump will be read from flash)', 'help': 'Path to core dump file (if skipped core dump will be read from flash)',
}, },
{
'names': ['--chip-rev'],
'help': 'Specify the chip revision (e.g., 0.1). If provided, the corresponding ROM ELF file will be used '
'for decoding the core dump, improving stack traces. This is only needed for core dumps from IDF '
'<v5.1. Newer versions already contain chip revision information.',
},
{ {
'names': ['--save-core', '-s'], 'names': ['--save-core', '-s'],
'help': 'Save core to file. Otherwise temporary core file will be deleted.', 'help': 'Save core to file. Otherwise temporary core file will be deleted.',
@@ -579,14 +608,14 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
{ {
'names': ['--openocd-scripts', '--openocd_scripts'], 'names': ['--openocd-scripts', '--openocd_scripts'],
'help': 'help':
('Script directory for openocd cfg files.\n'), ('Script directory for openocd cfg files.\n'),
'default': 'default':
None, None,
}, },
{ {
'names': ['--openocd-commands', '--openocd_commands'], 'names': ['--openocd-commands', '--openocd_commands'],
'help': 'help':
('Command line arguments for openocd.\n'), ('Command line arguments for openocd.\n'),
'default': None, 'default': None,
} }
], ],
@@ -618,9 +647,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
{ {
'names': ['--gdbgui-port', '--gdbgui_port'], 'names': ['--gdbgui-port', '--gdbgui_port'],
'help': 'help':
('The port on which gdbgui will be hosted. Default: 5000\n'), ('The port on which gdbgui will be hosted. Default: 5000\n'),
'default': 'default':
None, None,
}, gdbinit, fail_if_openocd_failed }, gdbinit, fail_if_openocd_failed
], ],
'order_dependencies': ['all', 'flash'], 'order_dependencies': ['all', 'flash'],
@@ -651,7 +680,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
{ {
'names': ['--block', '--block'], 'names': ['--block', '--block'],
'help': 'help':
('Set to 1 for blocking the console on the outputs of async debug actions\n'), ('Set to 1 for blocking the console on the outputs of async debug actions\n'),
'default': 0, 'default': 0,
}, },
], ],
@@ -671,7 +700,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
{ {
'names': ['--block', '--block'], 'names': ['--block', '--block'],
'help': 'help':
('Set to 1 for blocking the console on the outputs of async debug actions\n'), ('Set to 1 for blocking the console on the outputs of async debug actions\n'),
'default': 0, 'default': 0,
}, },
], ],