From 532ea1ad6d1c54b84ea55e22702af6aa71a61f28 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Thu, 22 May 2025 12:56:04 +0200 Subject: [PATCH] change(tools): fix the style of debug_ext.py --- tools/idf_py_actions/debug_ext.py | 224 +++++++++++++++++++----------- 1 file changed, 143 insertions(+), 81 deletions(-) diff --git a/tools/idf_py_actions/debug_ext.py b/tools/idf_py_actions/debug_ext.py index ccf744d20b..f14a635c44 100644 --- a/tools/idf_py_actions/debug_ext.py +++ b/tools/idf_py_actions/debug_ext.py @@ -19,14 +19,15 @@ from typing import Union from click import INT from click.core import Context from esp_coredump import CoreDump + from idf_py_actions.errors import FatalError from idf_py_actions.serial_ext import BAUD_RATE from idf_py_actions.serial_ext import PORT +from idf_py_actions.tools import PropertyDict from idf_py_actions.tools import ensure_build_directory from idf_py_actions.tools import generate_hints from idf_py_actions.tools import get_default_serial_port from idf_py_actions.tools import get_sdkconfig_value -from idf_py_actions.tools import PropertyDict from idf_py_actions.tools import yellow_print @@ -105,17 +106,19 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: print('Failed to close/kill {}'.format(target)) processes[target] = None # to indicate this has ended - def _get_espcoredump_instance(ctx: Context, - args: PropertyDict, - gdb_timeout_sec: Optional[int] = None, - core: Optional[str] = None, - chip_rev: Optional[str] = None, - save_core: Optional[str] = None) -> CoreDump: - + def _get_espcoredump_instance( + ctx: Context, + args: PropertyDict, + gdb_timeout_sec: Optional[int] = None, + core: Optional[str] = None, + chip_rev: Optional[str] = None, + save_core: Optional[str] = None, + ) -> CoreDump: ensure_build_directory(args, ctx.info_name) project_desc = get_project_desc(args, ctx) - coredump_to_flash_config = get_sdkconfig_value(project_desc['config_file'], - 'CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH') + coredump_to_flash_config = get_sdkconfig_value( + project_desc['config_file'], 'CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH' + ) 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']) @@ -141,13 +144,16 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: # The format will be determined automatically args.port = args.port or get_default_serial_port() else: - print('Path to core dump file is not provided. ' - "Core dump can't be read from flash since this option is not enabled in menuconfig") + print( + 'Path to core dump file is not provided. ' + "Core dump can't be read from flash since this option is not enabled in menuconfig" + ) sys.exit(1) espcoredump_kwargs['port'] = args.port - espcoredump_kwargs['parttable_off'] = get_sdkconfig_value(project_desc['config_file'], - 'CONFIG_PARTITION_TABLE_OFFSET') + espcoredump_kwargs['parttable_off'] = get_sdkconfig_value( + project_desc['config_file'], 'CONFIG_PARTITION_TABLE_OFFSET' + ) if save_core: espcoredump_kwargs['save_core'] = save_core @@ -169,8 +175,10 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: def is_gdb_with_python(gdb: str) -> bool: # execute simple python command to check is it supported - return subprocess.run([gdb, '--batch-silent', '--ex', 'python import os'], - stderr=subprocess.DEVNULL).returncode == 0 + return ( + subprocess.run([gdb, '--batch-silent', '--ex', 'python import os'], stderr=subprocess.DEVNULL).returncode + == 0 + ) def debug_cleanup() -> None: print('cleaning up debug targets') @@ -182,7 +190,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: _terminate_async_target('gdb') def post_debug(action: str, ctx: Context, args: PropertyDict, **kwargs: str) -> None: - """ Deal with asynchronous targets, such as openocd running in background """ + """Deal with asynchronous targets, such as openocd running in background""" if kwargs['block'] == 1: for target in ['openocd', 'gdbgui']: if target in processes and processes[target] is not None: @@ -216,8 +224,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: project_desc = json.load(f) return project_desc - def openocd(action: str, ctx: Context, args: PropertyDict, openocd_scripts: Optional[str], - openocd_commands: str) -> None: + def openocd( + action: str, ctx: Context, args: PropertyDict, openocd_scripts: Optional[str], openocd_commands: str + ) -> None: """ Execute openocd as external tool """ @@ -230,7 +239,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: openocd_arguments = project_desc.get('debug_arguments_openocd', '') print( 'Note: OpenOCD cfg not found (via env variable OPENOCD_COMMANDS nor as a --openocd-commands argument)\n' - 'OpenOCD arguments default to: "{}"'.format(openocd_arguments)) + 'OpenOCD arguments default to: "{}"'.format(openocd_arguments) + ) # script directory is taken from the environment by OpenOCD, update only if command line arguments to override if openocd_scripts is not None: openocd_arguments += ' -s {}'.format(openocd_scripts) @@ -243,14 +253,17 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: except Exception as e: print(e) raise FatalError( - 'Error starting openocd. Please make sure it is installed and is present in executable paths', ctx) + 'Error starting openocd. Please make sure it is installed and is present in executable paths', ctx + ) processes['openocd'] = process processes['openocd_outfile'] = openocd_out processes['openocd_outfile_name'] = openocd_out_name print('OpenOCD started as a background task {}'.format(process.pid)) - def get_gdb_args(project_desc: Dict[str, Any], gdb_x: Tuple, gdb_ex: Tuple, gdb_commands: Optional[str]) -> List[str]: + def get_gdb_args( + project_desc: Dict[str, Any], gdb_x: Tuple, gdb_ex: Tuple, gdb_commands: Optional[str] + ) -> List[str]: # check if the application was built and ELF file is in place. app_elf = os.path.join(project_desc.get('build_dir', ''), project_desc.get('app_elf', '')) if not os.path.exists(app_elf): @@ -260,13 +273,16 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: gdb_args = [gdb_name] gdbinit_files = project_desc.get('gdbinit_files') if not gdbinit_files: - raise FatalError('Please check if the project was configured correctly ("gdbinit_files" not found in "project_description.json").') + raise FatalError( + 'Please check if the project was configured correctly ("gdbinit_files" not found in ' + '"project_description.json").' + ) gdbinit_files = sorted(gdbinit_files.items()) gdb_x_list = list(gdb_x) gdb_x_names = [os.path.basename(x) for x in gdb_x_list] # compile predefined gdbinit files options. for name, path in gdbinit_files: - name = name[len('xx_'):] + name = name[len('xx_') :] if name == 'py_extensions': if not is_gdb_with_python(gdb_name): continue @@ -296,7 +312,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: def _get_gdbgui_version(ctx: Context) -> Tuple[int, ...]: subprocess_success = False try: - completed_process = subprocess.run(['gdbgui', '--version'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + completed_process = subprocess.run( + ['gdbgui', '--version'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) captured_output = completed_process.stdout.decode('utf-8', 'ignore') subprocess_success = True except FileNotFoundError: @@ -305,24 +323,39 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: if not subprocess_success or completed_process.returncode != 0: if sys.version_info[:2] >= (3, 11) and sys.platform == 'win32': - raise SystemExit('Unfortunately, gdbgui is supported only with Python 3.10 or older. ' - 'See: https://github.com/espressif/esp-idf/issues/10116. ' - 'Please use "idf.py gdb" or debug in Eclipse/Vscode instead.') + raise SystemExit( + 'Unfortunately, gdbgui is supported only with Python 3.10 or older. ' + 'See: https://github.com/espressif/esp-idf/issues/10116. ' + 'Please use "idf.py gdb" or debug in Eclipse/Vscode instead.' + ) if sys.version_info[:2] >= (3, 13) and sys.platform != 'win32': - raise SystemExit('Unfortunately, gdbgui is supported only with Python 3.12 or older. ' - 'See: https://github.com/cs01/gdbgui/issues/494. ' - 'Please use "idf.py gdb" or debug in Eclipse/Vscode instead.') - raise FatalError('Error starting gdbgui. Please make sure gdbgui has been installed with ' - '"install.{sh,bat,ps1,fish} --enable-gdbgui" and can be started. ' - f'Error: {captured_output if subprocess_success else "Unknown"}', ctx) + raise SystemExit( + 'Unfortunately, gdbgui is supported only with Python 3.12 or older. ' + 'See: https://github.com/cs01/gdbgui/issues/494. ' + 'Please use "idf.py gdb" or debug in Eclipse/Vscode instead.' + ) + raise FatalError( + 'Error starting gdbgui. Please make sure gdbgui has been installed with ' + '"install.{sh,bat,ps1,fish} --enable-gdbgui" and can be started. ' + f'Error: {captured_output if subprocess_success else "Unknown"}', + ctx, + ) v = re.search(r'(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?', captured_output) if not v: raise SystemExit(f'Error: "gdbgui --version" returned "{captured_output}"') return tuple(int(i) if i else 0 for i in (v[1], v[2], v[3], v[4])) - def gdbui(action: str, ctx: Context, args: PropertyDict, gdbgui_port: Optional[str], gdbinit: Tuple, - ex: Tuple, gdb_commands: Optional[str], require_openocd: bool) -> None: + def gdbui( + action: str, + ctx: Context, + args: PropertyDict, + gdbgui_port: Optional[str], + gdbinit: Tuple, + ex: Tuple, + gdb_commands: Optional[str], + require_openocd: bool, + ) -> None: """ Asynchronous GDB-UI target """ @@ -344,7 +377,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: # so for one item, use extra double quotes. for more items, use no extra double quotes. gdb = gdb_args[0] gdb_args_list = gdb_args[1:] - gdb_args_str = '"{}"'.format(' '.join(gdb_args_list)) if len(gdb_args_list) == 1 else ' '.join(gdb_args_list) + gdb_args_str = ( + '"{}"'.format(' '.join(gdb_args_list)) if len(gdb_args_list) == 1 else ' '.join(gdb_args_list) + ) gdbgui_args = ['gdbgui', '-g', gdb, '--gdb-args', gdb_args_str] if gdbgui_port is not None: @@ -396,18 +431,42 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: if task.name in ('gdb', 'gdbgui', 'gdbtui'): task.action_args['require_openocd'] = True - def gdbtui(action: str, ctx: Context, args: PropertyDict, gdbinit: Tuple, ex: Tuple, gdb_commands: str, require_openocd: bool) -> None: + def gdbtui( + action: str, + ctx: Context, + args: PropertyDict, + gdbinit: Tuple, + ex: Tuple, + gdb_commands: str, + require_openocd: bool, + ) -> None: """ Synchronous GDB target with text ui mode """ gdb(action, ctx, args, False, 1, gdbinit, ex, gdb_commands, require_openocd) - def gdb(action: str, ctx: Context, args: PropertyDict, batch: bool, gdb_tui: Optional[int], gdbinit: Tuple, - ex: Tuple, gdb_commands: Optional[str], require_openocd: bool) -> None: + def gdb( + action: str, + ctx: Context, + args: PropertyDict, + batch: bool, + gdb_tui: Optional[int], + gdbinit: Tuple, + ex: Tuple, + gdb_commands: Optional[str], + require_openocd: bool, + ) -> None: """ 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() processes['threads_to_join'].append(watch_openocd) project_desc = get_project_desc(args, ctx) @@ -433,25 +492,29 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: # Valid scenario: watch_openocd task won't be in the list if openocd not started from idf.py pass - def coredump_info(action: str, - ctx: Context, - args: PropertyDict, - gdb_timeout_sec: int, - core: Optional[str] = None, - chip_rev: Optional[str] = None, - save_core: Optional[str] = None) -> None: - espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, gdb_timeout_sec=gdb_timeout_sec, core=core, - chip_rev=chip_rev, - save_core=save_core) + def coredump_info( + action: str, + ctx: Context, + args: PropertyDict, + gdb_timeout_sec: int, + core: Optional[str] = None, + chip_rev: Optional[str] = None, + save_core: Optional[str] = None, + ) -> None: + espcoredump = _get_espcoredump_instance( + ctx=ctx, args=args, gdb_timeout_sec=gdb_timeout_sec, core=core, chip_rev=chip_rev, save_core=save_core + ) espcoredump.info_corefile() - def coredump_debug(action: str, - ctx: Context, - args: PropertyDict, - core: Optional[str] = None, - chip_rev: Optional[str] = None, - save_core: Optional[str] = None) -> None: + def coredump_debug( + action: str, + ctx: Context, + args: PropertyDict, + core: Optional[str] = None, + chip_rev: Optional[str] = None, + save_core: Optional[str] = None, + ) -> None: espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, core=core, chip_rev=chip_rev, save_core=save_core) espcoredump.dbg_corefile() @@ -464,8 +527,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: { '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 ' - 'ESP-IDF older than v5.2. Newer versions already contain chip revision information.', + 'for decoding the core dump, improving stack traces. This is only needed for core dumps from ' + 'ESP-IDF older than v5.2. Newer versions already contain chip revision information.', 'hidden': True, }, { @@ -493,15 +556,13 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: } ex = { 'names': ['--ex', '-ex'], - 'help': - ('Execute given GDB command.\n'), + 'help': ('Execute given GDB command.\n'), 'default': None, 'multiple': True, } gdb_commands = { 'names': ['--gdb-commands', '--gdb_commands'], - 'help': - ('Command line arguments for gdb.\n'), + 'help': ('Command line arguments for gdb.\n'), 'default': None, } debug_actions = { @@ -513,17 +574,14 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'options': [ { 'names': ['--openocd-scripts', '--openocd_scripts'], - 'help': - ('Script directory for openocd cfg files.\n'), - 'default': - None, + 'help': ('Script directory for openocd cfg files.\n'), + 'default': None, }, { 'names': ['--openocd-commands', '--openocd_commands'], - 'help': - ('Command line arguments for openocd.\n'), + 'help': ('Command line arguments for openocd.\n'), 'default': None, - } + }, ], 'order_dependencies': ['all', 'flash'], }, @@ -542,7 +600,11 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'names': ['--gdb-tui', '--gdb_tui'], 'help': ('run gdb in TUI mode\n'), 'default': None, - }, gdbinit, ex, gdb_commands, fail_if_openocd_failed + }, + gdbinit, + ex, + gdb_commands, + fail_if_openocd_failed, ], 'order_dependencies': ['all', 'flash'], }, @@ -552,11 +614,13 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'options': [ { 'names': ['--gdbgui-port', '--gdbgui_port'], - 'help': - ('The port on which gdbgui will be hosted. Default: 5000\n'), - 'default': - None, - }, gdbinit, ex, gdb_commands, fail_if_openocd_failed + 'help': ('The port on which gdbgui will be hosted. Default: 5000\n'), + 'default': None, + }, + gdbinit, + ex, + gdb_commands, + fail_if_openocd_failed, ], 'order_dependencies': ['all', 'flash'], }, @@ -569,7 +633,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'coredump-info': { 'callback': coredump_info, 'help': 'Print crashed task’s registers, callstack, list of available tasks in the system, ' - 'memory regions and contents of memory stored in core dump (TCBs and stacks)', + 'memory regions and contents of memory stored in core dump (TCBs and stacks)', 'options': coredump_base + [PORT, BAUD_RATE, gdb_timeout_sec_opt], # type: ignore 'order_dependencies': ['all', 'flash'], }, @@ -585,8 +649,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'options': [ { 'names': ['--block', '--block'], - 'help': - ('Set to 1 for blocking the console on the outputs of async debug actions\n'), + 'help': ('Set to 1 for blocking the console on the outputs of async debug actions\n'), 'default': 0, }, ], @@ -605,8 +668,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'options': [ { 'names': ['--block', '--block'], - 'help': - ('Set to 1 for blocking the console on the outputs of async debug actions\n'), + 'help': ('Set to 1 for blocking the console on the outputs of async debug actions\n'), 'default': 0, }, ],