44from collections import defaultdict
55from itertools import count
66from enum import Enum
7+ import platform
78import sys
89from _remote_debugging import get_all_awaited_by
910
@@ -184,6 +185,83 @@ def _print_cycle_exception(exception: CycleFoundException):
184185 print (f"cycle: { inames } " , file = sys .stderr )
185186
186187
188+ LINUX_PERMISSION_HELP_TEXT = """
189+ Error: The specified process cannot be attached to due to insufficient
190+ permissions.
191+
192+ This could be because the tracer lacks the required capability
193+ (CAP_SYS_PTRACE), or because the process is already being traced. Additionally,
194+ security restrictions may prevent attaching to processes you cannot signal, or
195+ those running with set-user-ID/set-group-ID.
196+
197+ If you are trying to attach to a process you own, you can try the following:
198+
199+ * Re-run the command with elevated privileges, for example: 'sudo -E !!'
200+
201+ * Temporarily relax ptrace restrictions for the current session (until reboot)
202+ by running:
203+ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
204+
205+ Note: Disabling ptrace scope reduces system hardening and should only be done
206+ in trusted environments.
207+ """
208+
209+ MACOS_PERMISSION_HELP_TEXT = """
210+ Error: The specified process cannot be attached to due to insufficient
211+ permissions.
212+
213+ Try re-running the command with elevated privileges (e.g., using 'sudo'):
214+
215+ sudo python -m pdb -p <PID>
216+
217+ Note: Security restrictions may block debugging even for processes you own
218+ unless run with root privileges.
219+ """
220+
221+ WINDOWS_PERMISSION_HELP_TEXT = """
222+ Error: The specified process cannot be attached to due to insufficient
223+ permissions.
224+
225+ Try running the command prompt or terminal as Administrator and re-run the
226+ command.
227+
228+ Note: Some processes may still be inaccessible without special privileges such
229+ as 'SeDebugPrivilege', even when running as Administrator.
230+
231+ To adjust file or folder permissions:
232+
233+ 1. Right-click the file or folder and select "Properties".
234+ 2. Go to the "Security" tab. At the top, you'll see a list of users and groups
235+ with current access.
236+ 3. Click "Edit" to change permissions.
237+ 4. In the "Group or user names" section, select your user account.
238+ 5. In the "Permissions" section below, check "Read" or "Full control" as needed.
239+ 6. Click "Apply", then "OK" to confirm changes.
240+ """
241+
242+
243+ def exit_with_permission_help_text ():
244+ """
245+ Prints platform-specific permission help text and exits the program.
246+
247+ This function is called when a PermissionError is encountered while trying
248+ to attach to a process.
249+ """
250+ system = platform .system ()
251+ if system == "Linux" :
252+ print (LINUX_PERMISSION_HELP_TEXT )
253+ elif system == "Darwin" :
254+ print (MACOS_PERMISSION_HELP_TEXT )
255+ elif system == "Windows" :
256+ print (WINDOWS_PERMISSION_HELP_TEXT )
257+ else :
258+ print (
259+ "Permission denied when trying to attach to the process. "
260+ "Make sure you have sufficient privileges."
261+ )
262+ sys .exit (1 )
263+
264+
187265def _get_awaited_by_tasks (pid : int ) -> list :
188266 try :
189267 return get_all_awaited_by (pid )
@@ -192,6 +270,8 @@ def _get_awaited_by_tasks(pid: int) -> list:
192270 e = e .__context__
193271 print (f"Error retrieving tasks: { e } " )
194272 sys .exit (1 )
273+ except PermissionError as e :
274+ exit_with_permission_help_text ()
195275
196276
197277def display_awaited_by_tasks_table (pid : int ) -> None :
0 commit comments