[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:
Miss Islington (bot) 2025-09-12 14:20:20 +02:00 committed by GitHub
parent 5210e307ae
commit 664d17f97a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 109 additions and 1 deletions

View file

@ -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.

View file

@ -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:

View file

@ -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

View file

@ -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()