mirror of
https://github.com/python/cpython.git
synced 2025-11-09 01:51:26 +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
|
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
|
This section describes the low-level protocol that enables external tools to
|
||||||
inject and execute a Python script within a running CPython process.
|
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)
|
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:
|
def _get_awaited_by_tasks(pid: int) -> list:
|
||||||
try:
|
try:
|
||||||
return get_all_awaited_by(pid)
|
return get_all_awaited_by(pid)
|
||||||
|
|
@ -230,6 +244,8 @@ def _get_awaited_by_tasks(pid: int) -> list:
|
||||||
e = e.__context__
|
e = e.__context__
|
||||||
print(f"Error retrieving tasks: {e}")
|
print(f"Error retrieving tasks: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
except PermissionError as e:
|
||||||
|
exit_with_permission_help_text()
|
||||||
|
|
||||||
|
|
||||||
def display_awaited_by_tasks_table(pid: int) -> None:
|
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'"."""
|
"-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():
|
def main():
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|
@ -3538,7 +3552,10 @@ def main():
|
||||||
opts = parser.parse_args()
|
opts = parser.parse_args()
|
||||||
if opts.module:
|
if opts.module:
|
||||||
parser.error("argument -m: not allowed with argument --pid")
|
parser.error("argument -m: not allowed with argument --pid")
|
||||||
|
try:
|
||||||
attach(opts.pid, opts.commands)
|
attach(opts.pid, opts.commands)
|
||||||
|
except PermissionError as e:
|
||||||
|
exit_with_permission_help_text()
|
||||||
return
|
return
|
||||||
elif opts.module:
|
elif opts.module:
|
||||||
# If a module is being debugged, we consider the arguments after "-m module" to
|
# 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_stdout(client_stdout),
|
||||||
redirect_stderr(client_stderr),
|
redirect_stderr(client_stderr),
|
||||||
unittest.mock.patch("sys.argv", ["pdb", "-p", str(process.pid)]),
|
unittest.mock.patch("sys.argv", ["pdb", "-p", str(process.pid)]),
|
||||||
|
unittest.mock.patch(
|
||||||
|
"pdb.exit_with_permission_help_text", side_effect=PermissionError
|
||||||
|
),
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
pdb.main()
|
pdb.main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue