@@ -132,24 +132,27 @@ Runtime State Extensions
132132
133133A new structure is added to PyThreadState to support remote debugging:
134134
135+ debugging:
136+
135137.. code-block :: C
136138
137139 typedef struct _remote_debugger_support {
138140 int debugger_pending_call;
139- char debugger_script[MAX_SCRIPT_SIZE];
141+ char debugger_script_path[MAX_SCRIPT_PATH_SIZE];
142+ char *debugger_buffer;
143+ Py_ssize_t debugger_buffer_size;
140144 } _PyRemoteDebuggerSupport;
141145
142-
143146 This structure is appended to ``PyThreadState ``, adding only a few fields that
144147are **never accessed during normal execution **. The ``debugger_pending_call `` field
145148indicates when a debugger has requested execution, while ``debugger_script ``
146149provides Python code to be executed when the interpreter reaches a safe point.
147150
148- The value for ``MAX_SCRIPT_SIZE `` will be a trade-off between binary size and
149- how big debugging scripts can be. As most of the logic should be in libraries
150- and arbitrary code can be executed with very short amount of Python we are
151- proposing to start with 4kb initially. This value can be extended in the future
152- if we ever need to.
151+ The value for ``MAX_SCRIPT_PATH_SIZE `` will be a trade-off between binary size
152+ and how big debugging scripts paths can be. To limit the memory overhead per
153+ thread we will be limiting this to 512 bytes. This size will also be provided as
154+ part of the debugger support structure so debuggers know how much they can
155+ write. This value can be extended in the future if we ever need to.
153156
154157
155158Debug Offsets Table
@@ -201,7 +204,7 @@ When a debugger wants to attach to a Python process, it follows these steps:
201204
202205 - Write a filename containing Python code to be executed into the
203206 ``debugger_script `` field in ``_PyRemoteDebuggerSupport ``.
204- - Set ``debugger_pending_call `` flag in ``_PyRemoteDebuggerSupport ``
207+ - Set ``debugger_pending_call `` flag in ``_PyRemoteDebuggerSupport `` to 1
205208 - Set ``_PY_EVAL_PLEASE_STOP_BIT `` in the ``eval_breaker `` field
206209
207210Once the interpreter reaches the next safe point, it will execute the script
@@ -224,6 +227,9 @@ the interpreter will execute the provided debugging code at the next safe point.
224227This all happens in a completely safe context, since the interpreter is
225228guaranteed to be in a consistent state whenever the eval breaker is checked.
226229
230+ The only valid values for ``debugger_pending_call `` will initially be 0 and 1
231+ and other values are reserved for future use.
232+
227233An audit event will be raised before the code is executed, allowing this mechanism
228234to be audited or disabled if desired by a system's administrator.
229235
@@ -464,6 +470,21 @@ in the file path to point to somewhere attacker controlled, this would allow
464470them to force their malicious code to be executed rather than the code the
465471debugger intends to run.
466472
473+ Using a Single Runtime Buffer
474+ -----------------------------------
475+
476+ During the review of this PEP it has been suggested using a single
477+ shared buffer at the runtime level for all debugger communications. While this
478+ appeared simpler and requring less memory , we discovered it would actually prevent scenarios
479+ where multiple debuggers need to coordinate operations across different threads,
480+ or where a single debugger needs to orchestrate complex debugging operations. A
481+ single shared buffer would force serialization of all debugging operations,
482+ making it impossible for debuggers to work independently on different threads.
483+
484+ The per-thread buffer approach, despite its memory overhead in highly threaded
485+ applications, enables these important debugging scenarios by allowing each
486+ debugger to communicate independently with its target thread.
487+
467488Thanks
468489======
469490
0 commit comments