mirror of
https://github.com/python/cpython.git
synced 2025-11-08 17:41:42 +00:00
[3.14] Improve permission error messages in pdb and asyncio.tools (GH-134290) (#138826)
Improve permission error messages in pdb and asyncio.tools (GH-134290)
(cherry picked from commit 419441a6e1)
Co-authored-by: ivonastojanovic <80911834+ivonastojanovic@users.noreply.github.com>
This commit is contained in:
parent
5210e307ae
commit
664d17f97a
4 changed files with 109 additions and 1 deletions
|
|
@ -3,6 +3,78 @@
|
|||
Remote debugging attachment protocol
|
||||
====================================
|
||||
|
||||
This protocol enables external tools to attach to a running CPython process and
|
||||
execute Python code remotely.
|
||||
|
||||
Most platforms require elevated privileges to attach to another Python process.
|
||||
|
||||
.. _permission-requirements:
|
||||
|
||||
Permission requirements
|
||||
=======================
|
||||
|
||||
Attaching to a running Python process for remote debugging requires elevated
|
||||
privileges on most platforms. The specific requirements and troubleshooting
|
||||
steps depend on your operating system:
|
||||
|
||||
.. rubric:: Linux
|
||||
|
||||
The tracer process must have the ``CAP_SYS_PTRACE`` capability or equivalent
|
||||
privileges. You can only trace processes you own and can signal. Tracing may
|
||||
fail if the process is already being traced, or if it is running with
|
||||
set-user-ID or set-group-ID. Security modules like Yama may further restrict
|
||||
tracing.
|
||||
|
||||
To temporarily relax ptrace restrictions (until reboot), run:
|
||||
|
||||
``echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope``
|
||||
|
||||
.. note::
|
||||
|
||||
Disabling ``ptrace_scope`` reduces system hardening and should only be done
|
||||
in trusted environments.
|
||||
|
||||
If running inside a container, use ``--cap-add=SYS_PTRACE`` or
|
||||
``--privileged``, and run as root if needed.
|
||||
|
||||
Try re-running the command with elevated privileges:
|
||||
|
||||
``sudo -E !!``
|
||||
|
||||
|
||||
.. rubric:: macOS
|
||||
|
||||
To attach to another process, you typically need to run your debugging tool
|
||||
with elevated privileges. This can be done by using ``sudo`` or running as
|
||||
root.
|
||||
|
||||
Even when attaching to processes you own, macOS may block debugging unless
|
||||
the debugger is run with root privileges due to system security restrictions.
|
||||
|
||||
|
||||
.. rubric:: Windows
|
||||
|
||||
To attach to another process, you usually need to run your debugging tool
|
||||
with administrative privileges. Start the command prompt or terminal as
|
||||
Administrator.
|
||||
|
||||
Some processes may still be inaccessible even with Administrator rights,
|
||||
unless you have the ``SeDebugPrivilege`` privilege enabled.
|
||||
|
||||
To resolve file or folder access issues, adjust the security permissions:
|
||||
|
||||
1. Right-click the file or folder and select **Properties**.
|
||||
2. Go to the **Security** tab to view users and groups with access.
|
||||
3. Click **Edit** to modify permissions.
|
||||
4. Select your user account.
|
||||
5. In **Permissions**, check **Read** or **Full control** as needed.
|
||||
6. Click **Apply**, then **OK** to confirm.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Ensure you've satisfied all :ref:`permission-requirements` before proceeding.
|
||||
|
||||
This section describes the low-level protocol that enables external tools to
|
||||
inject and execute a Python script within a running CPython process.
|
||||
|
||||
|
|
|
|||
|
|
@ -222,6 +222,20 @@ def _print_cycle_exception(exception: CycleFoundException):
|
|||
print(f"cycle: {inames}", file=sys.stderr)
|
||||
|
||||
|
||||
def exit_with_permission_help_text():
|
||||
"""
|
||||
Prints a message pointing to platform-specific permission help text and exits the program.
|
||||
This function is called when a PermissionError is encountered while trying
|
||||
to attach to a process.
|
||||
"""
|
||||
print(
|
||||
"Error: The specified process cannot be attached to due to insufficient permissions.\n"
|
||||
"See the Python documentation for details on required privileges and troubleshooting:\n"
|
||||
"https://docs.python.org/3.14/howto/remote_debugging.html#permission-requirements\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def _get_awaited_by_tasks(pid: int) -> list:
|
||||
try:
|
||||
return get_all_awaited_by(pid)
|
||||
|
|
@ -230,6 +244,8 @@ def _get_awaited_by_tasks(pid: int) -> list:
|
|||
e = e.__context__
|
||||
print(f"Error retrieving tasks: {e}")
|
||||
sys.exit(1)
|
||||
except PermissionError as e:
|
||||
exit_with_permission_help_text()
|
||||
|
||||
|
||||
def display_awaited_by_tasks_table(pid: int) -> None:
|
||||
|
|
|
|||
17
Lib/pdb.py
17
Lib/pdb.py
|
|
@ -3505,6 +3505,20 @@ def help():
|
|||
"-c 'until X'"."""
|
||||
|
||||
|
||||
def exit_with_permission_help_text():
|
||||
"""
|
||||
Prints a message pointing to platform-specific permission help text and exits the program.
|
||||
This function is called when a PermissionError is encountered while trying
|
||||
to attach to a process.
|
||||
"""
|
||||
print(
|
||||
"Error: The specified process cannot be attached to due to insufficient permissions.\n"
|
||||
"See the Python documentation for details on required privileges and troubleshooting:\n"
|
||||
"https://docs.python.org/3.14/howto/remote_debugging.html#permission-requirements\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
|
|
@ -3538,7 +3552,10 @@ def main():
|
|||
opts = parser.parse_args()
|
||||
if opts.module:
|
||||
parser.error("argument -m: not allowed with argument --pid")
|
||||
try:
|
||||
attach(opts.pid, opts.commands)
|
||||
except PermissionError as e:
|
||||
exit_with_permission_help_text()
|
||||
return
|
||||
elif opts.module:
|
||||
# If a module is being debugged, we consider the arguments after "-m module" to
|
||||
|
|
|
|||
|
|
@ -1539,6 +1539,9 @@ def do_integration_test(self, client_stdin):
|
|||
redirect_stdout(client_stdout),
|
||||
redirect_stderr(client_stderr),
|
||||
unittest.mock.patch("sys.argv", ["pdb", "-p", str(process.pid)]),
|
||||
unittest.mock.patch(
|
||||
"pdb.exit_with_permission_help_text", side_effect=PermissionError
|
||||
),
|
||||
):
|
||||
try:
|
||||
pdb.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue