mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
6f8c62b205
idf.py spawns gdb process within a thread and uses Thread.join() to wait for the gdb process to finish. As CTRL+C(SIGINT) is used by gdb to interrupt the running program, we catch the SIGINT while waiting on the gdb to finish, and try Thread.join() again. With cpython's commit commit a22be4943c119fecf5433d999227ff78fc2e5741 Author: Victor Stinner <vstinner@python.org> Date: Mon Sep 27 14:20:31 2021 +0200 bpo-45274: Fix Thread._wait_for_tstate_lock() race condition (GH-28532) this logic doesn't work anymore, because cpython internally marks the thread as stopped when join() is interrupted with an exception. IMHO this is broken in cpython and there is a bug report about this https://github.com/python/cpython/issues/90882. Problem is that waiting on a thread to finish is based on acquiring a lock. Meaning join() is waiting on _tstate_lock. If this wait is interrupted, the above referenced commit adds a logic that checks if the lock is help, meaning the thread is done and marks the thread as stopped. But there is no way to tell if the lock was acquired by us running join() or if it's held by someone else e.g. still by the thread bootstrap code. Meaning the thread is still running. I may be missing something, but I don't see any reason why to spawn gdb process within a thread. This change removes the thread and spawns gdb directly. Instead waiting on a thread, we wait on the process to finish, replacing join() with wait() and avoiding this problem. Closes https://github.com/espressif/esp-idf/issues/11871 Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com> |
||
---|---|---|
.. | ||
__init__.py | ||
constants.py | ||
core_ext.py | ||
create_ext.py | ||
debug_ext.py | ||
dfu_ext.py | ||
errors.py | ||
global_options.py | ||
hints.yml | ||
README.md | ||
roms_schema.json | ||
roms.json | ||
serial_ext.py | ||
tools.py | ||
uf2_ext.py |
idf.py extensions
Python modules (subdirectories and files) in this directory named [your_extension]_ext
will be loaded as idf.py extensions.
If you want to provide extra extensions just provide ;
separated list of directories with extensions in IDF_EXTRA_ACTIONS_PATH
. Extensions will be loaded in alphanumeric order.
Command line arguments parsing and extension mechanism is implemented on top of Click (versions >=5.0 are supported).
They should define a function action_extensions(base_actions, project_path)
where:
- base_actions - dictionary with actions that are already available for idf.py
- project_path - working dir, may be defaulted to
os.getcwd()
This function have to return a dict with 3 possible keys:
{
# Additional options that will be available from id
"global_options": [{
"names": ["--option-name"],
"help": "Help for option --option-name.",
}],
# List of functions that will have access to full app context, and can mangle with arguments
"global_action_callbacks": [global_callback],
# Additional subcommands for idf.py
"actions": {
"subcommand_name": {
"callback": subcommand_callback,
"help": "Help for subcommand.",
},
},
}
Where function global_callback(ctx, global_args, tasks)
accepts 3 arguments:
- ctx - Click context
- global_args - dictionary of all available global arguments
- tasks - list of Task objects
And subcommand_callback(subcommand_name, ctx, args)
accepts 3 arguments:
- subcommand_name - name of subcommand
- ctx - Click context
- args - list of command's arguments