mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'break/drop_gdbgui' into 'master'
Tools: Drop official support for gdbgui Closes IDF-4627 See merge request espressif/esp-idf!39326
This commit is contained in:
@ -232,7 +232,7 @@ It is also possible to execute the described debugging tools conveniently from `
|
||||
|
||||
4. ``idf.py gdbgui``
|
||||
|
||||
Starts `gdbgui <https://www.gdbgui.com>`_ debugger frontend enabling out-of-the-box debugging in a browser window. To enable this option, run the install script with the "--enable-gdbgui" argument, e.g., ``install.sh --enable-gdbgui``.
|
||||
Starts `gdbgui <https://www.gdbgui.com>`_ debugger frontend, which enables out-of-the-box debugging in a browser window. To enable this option, follow the `installation instructions <https://www.gdbgui.com/installation/>`_ to set up the tool using the ``pipx`` method. For system dependencies, restrictions, and other limitations, please refer to the installation page and the `issue tracker <https://github.com/cs01/gdbgui/issues>`_.
|
||||
|
||||
|
||||
You can combine these debugging actions on a single command line, allowing for convenient setup of blocking and non-blocking actions in one step. ``idf.py`` implements a simple logic to move the background actions (such as openocd) to the beginning and the interactive ones (such as gdb, monitor) to the end of the action list.
|
||||
|
@ -7,3 +7,4 @@ Migration from 5.5 to 6.0
|
||||
:maxdepth: 1
|
||||
|
||||
peripherals
|
||||
tools
|
||||
|
25
docs/en/migration-guides/release-6.x/6.0/tools.rst
Normal file
25
docs/en/migration-guides/release-6.x/6.0/tools.rst
Normal file
@ -0,0 +1,25 @@
|
||||
Tools
|
||||
=====
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
GDBGUI installation
|
||||
-------------------
|
||||
|
||||
The support for the ``--enable-gdbgui`` argument has been removed from the install scripts and `gdbgui <https://www.gdbgui.com>`_ cannot be installed this way anymore. Please use the ``pipx`` method from the `gdbgui installation guide <https://www.gdbgui.com/installation/>`_ in order to set up this tool.
|
||||
|
||||
Depending on your operating system and Python version, you may need to consult the `list of known issues <https://github.com/cs01/gdbgui/issues>`_.
|
||||
|
||||
For example, `Python 3.13 is not supported <https://github.com/cs01/gdbgui/issues/494>`_ on any operating systems at the moment.
|
||||
|
||||
The Windows operating system is not supported since gdbgui version 0.14. Because of the existence of other issues, you will need Python 3.10 with some specific versions of the dependencies. The last know working gdbgui and dependency versions can be installed with the following command:
|
||||
|
||||
```bash
|
||||
pipx install "gdbgui==0.13.2.0" "pygdbmi<=0.9.0.2" "python-socketio<5" "jinja2<3.1" "itsdangerous<2.1"
|
||||
```
|
||||
|
||||
On Linux or MacOS, you can use Python 3.11 or 3.12 and gdbgui version 0.15.2.0.
|
||||
|
||||
Please be aware that these recommendations may change over time and for an up-to-date list of issues refer to `the official issue tracker <https://github.com/cs01/gdbgui/issues>`_.
|
||||
|
||||
We recommend to use ``idf.py gdb`` instead of ``idf.py gdbgui``, or debug in Eclipse/Vscode if you encounter an issue with the installation.
|
@ -232,7 +232,7 @@
|
||||
|
||||
4. ``idf.py gdbgui``
|
||||
|
||||
启动 `gdbgui <https://www.gdbgui.com>`_,在浏览器中打开调试器的前端界面。请在运行安装脚本时添加 "--enable-gdbgui" 参数,即运行 ``install.sh --enable-gdbgui``,从而确保支持 ``gdbgui`` 选项。
|
||||
启动 `gdbgui <https://www.gdbgui.com>`_,在浏览器中打开调试器的前端界面。要启用此选项,请参照 `安装说明 <https://www.gdbgui.com/installation/>`_,使用 ``pipx`` 方法设置该工具。关于系统依赖项、限制及其他注意事项,请参考安装页面和 `问题追踪 <https://github.com/cs01/gdbgui/issues>`_。
|
||||
|
||||
|
||||
上述这些命令也可以合并到一起使用,``idf.py`` 会自动将后台进程(比如 openocd)最先运行,交互式进程(比如 GDB,monitor)最后运行。
|
||||
|
@ -7,3 +7,4 @@
|
||||
:maxdepth: 1
|
||||
|
||||
peripherals
|
||||
tools
|
||||
|
1
docs/zh_CN/migration-guides/release-6.x/6.0/tools.rst
Normal file
1
docs/zh_CN/migration-guides/release-6.x/6.0/tools.rst
Normal file
@ -0,0 +1 @@
|
||||
.. include:: ../../../../en/migration-guides/release-6.x/6.0/tools.rst
|
@ -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:
|
||||
@ -304,25 +322,27 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
pass
|
||||
|
||||
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.')
|
||||
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(
|
||||
'Error occurred while starting gdbgui. Please make sure gdbgui has been installed with '
|
||||
'pipx based on https://www.gdbgui.com/installation/ and "gdbgui --version" can be run '
|
||||
'successfully. Gdbgui issues can be reported at https://github.com/cs01/gdbgui/issues.'
|
||||
)
|
||||
|
||||
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 +364,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 +418,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 +479,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 +514,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 +543,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 +561,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 +587,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 +601,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 +620,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 +636,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 +655,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,
|
||||
},
|
||||
],
|
||||
|
@ -7,12 +7,6 @@
|
||||
"optional": false,
|
||||
"requirement_path": "tools/requirements/requirements.core.txt"
|
||||
},
|
||||
{
|
||||
"name": "gdbgui",
|
||||
"description": "Packages for supporting debugging from web browser",
|
||||
"optional": true,
|
||||
"requirement_path": "tools/requirements/requirements.gdbgui.txt"
|
||||
},
|
||||
{
|
||||
"name": "pytest",
|
||||
"description": "Packages for CI with pytest",
|
||||
|
@ -1,12 +0,0 @@
|
||||
# Python package requirements for gdbgui support ESP-IDF.
|
||||
# This feature can be enabled by running "install.{sh,bat,ps1,fish} --enable-gdbgui"
|
||||
#
|
||||
# This file lists Python packages without version specifiers. Version details
|
||||
# are stored in a separate constraints file. For more information, visit:
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/idf-tools.html
|
||||
|
||||
# gdbgui Python 3.11 issue https://github.com/cs01/gdbgui/issues/447 was fixed in 0.15.2.0. Windows users need an
|
||||
# older Python to use since new gdbgui versions don't support Windows anymore.
|
||||
# Python 3.13 is not supported: https://github.com/cs01/gdbgui/issues/494
|
||||
gdbgui; sys_platform != 'win32' and python_version < "3.13"
|
||||
gdbgui; sys_platform == 'win32' and python_version < "3.11"
|
@ -23,7 +23,7 @@ except ImportError:
|
||||
sys.path.append('..')
|
||||
import idf_tools
|
||||
|
||||
IDF_PATH = os.environ.get('IDF_PATH', '../..')
|
||||
IDF_PATH = os.path.abspath(os.environ.get('IDF_PATH', '../..'))
|
||||
TOOLS_DIR = os.environ.get('IDF_TOOLS_PATH') or os.path.expanduser(idf_tools.IDF_TOOLS_PATH_DEFAULT)
|
||||
PYTHON_DIR = os.path.join(TOOLS_DIR, 'python_env')
|
||||
PYTHON_DIR_BACKUP = tempfile.mkdtemp()
|
||||
@ -32,7 +32,7 @@ REQ_SATISFIED = 'Python requirements are satisfied'
|
||||
# Python 3.8 and 3.9 has a different error message that does not include the "No package metadata was found for" part
|
||||
REQ_MISSING = r'Package was not found and is required by the application: (No package metadata was found for )?{}'
|
||||
REQ_CORE = '- {}'.format(os.path.join(IDF_PATH, 'tools', 'requirements', 'requirements.core.txt'))
|
||||
REQ_GDBGUI = '- {}'.format(os.path.join(IDF_PATH, 'tools', 'requirements', 'requirements.gdbgui.txt'))
|
||||
REQ_DOCS = '- {}'.format(os.path.join(IDF_PATH, 'tools', 'requirements', 'requirements.docs.txt'))
|
||||
CONSTR = 'Constraint file: {}'.format(os.path.join(TOOLS_DIR, 'espidf.constraints'))
|
||||
|
||||
# Set default global paths for idf_tools. If some test needs to
|
||||
@ -191,29 +191,29 @@ class TestPythonInstall(BasePythonInstall):
|
||||
output = self.run_idf_tools(['install-python-env'])
|
||||
self.assertIn(CONSTR, output)
|
||||
self.assertIn(REQ_CORE, output)
|
||||
self.assertNotIn(REQ_GDBGUI, output)
|
||||
self.assertNotIn(REQ_DOCS, output)
|
||||
|
||||
output = self.run_idf_tools(['check-python-dependencies'])
|
||||
self.assertIn(REQ_SATISFIED, output)
|
||||
|
||||
def test_opt_argument(self): # type: () -> None
|
||||
output = self.run_idf_tools(['install-python-env', '--features', 'gdbgui'])
|
||||
output = self.run_idf_tools(['install-python-env', '--features', 'docs'])
|
||||
self.assertIn(CONSTR, output)
|
||||
self.assertIn(REQ_CORE, output)
|
||||
self.assertIn(REQ_GDBGUI, output)
|
||||
self.assertIn(REQ_DOCS, output)
|
||||
|
||||
output = self.run_idf_tools(['install-python-env'])
|
||||
# The gdbgui should be installed as well because the feature is is stored in the JSON file
|
||||
# The docs should be installed as well because the feature is is stored in the JSON file
|
||||
self.assertIn(CONSTR, output)
|
||||
self.assertIn(REQ_CORE, output)
|
||||
self.assertIn(REQ_GDBGUI, output)
|
||||
self.assertIn(REQ_DOCS, output)
|
||||
|
||||
# Argument that begins with '-' can't stand alone to be parsed as value
|
||||
output = self.run_idf_tools(['install-python-env', '--features=-gdbgui'])
|
||||
# After removing the gdbgui should not be present
|
||||
output = self.run_idf_tools(['install-python-env', '--features=-docs'])
|
||||
# After removing the docs should not be present
|
||||
self.assertIn(CONSTR, output)
|
||||
self.assertIn(REQ_CORE, output)
|
||||
self.assertNotIn(REQ_GDBGUI, output)
|
||||
self.assertNotIn(REQ_DOCS, output)
|
||||
|
||||
def test_no_constraints(self): # type: () -> None
|
||||
output = self.run_idf_tools(['install-python-env', '--no-constraints'])
|
||||
|
Reference in New Issue
Block a user