Skip to content

Commit a2567dc

Browse files
committed
WS1
design-docs/balanced-call-stack-events-implementation-plan.status.md: Signed-off-by: Tzanko Matev <[email protected]>
1 parent 3073265 commit a2567dc

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

codetracer-python-recorder/src/runtime/tracer/events.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,16 @@ pub(super) fn suppress_events() -> bool {
158158

159159
impl Tracer for RuntimeTracer {
160160
fn interest(&self, events: &MonitoringEvents) -> EventSet {
161-
// Minimal set: function start, step lines, and returns
162-
events_union(&[events.PY_START, events.LINE, events.PY_RETURN])
161+
// Balanced call stack requires tracking yields, resumes, throws, and unwinds
162+
events_union(&[
163+
events.PY_START,
164+
events.PY_RETURN,
165+
events.PY_YIELD,
166+
events.PY_UNWIND,
167+
events.PY_RESUME,
168+
events.PY_THROW,
169+
events.LINE,
170+
])
163171
}
164172

165173
fn on_py_start(
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Balanced Call Stack Events – Status
2+
3+
## Relevant Design Docs
4+
- `design-docs/adr/0012-balanced-call-stack-events.md`
5+
- `design-docs/balanced-call-stack-events-implementation-plan.md`
6+
- `design-docs/design-001.md` (monitoring architecture reference)
7+
8+
## Key Source Files
9+
- `codetracer-python-recorder/src/runtime/tracer/events.rs`
10+
- `codetracer-python-recorder/src/monitoring/mod.rs`
11+
- `codetracer-python-recorder/src/monitoring/install.rs`
12+
- `codetracer-python-recorder/src/monitoring/callbacks.rs`
13+
- `codetracer-python-recorder/src/runtime/tracer/runtime_tracer.rs`
14+
- `codetracer-python-recorder/tests/python/test_monitoring_events.py`
15+
- `codetracer-python-recorder/tests/rust/print_tracer.rs`
16+
17+
## Workstream Progress
18+
19+
### WS1 – Monitoring Mask & Callback Wiring
20+
- **Scope recap:** Update `RuntimeTracer::interest` to include `PY_YIELD`, `PY_UNWIND`, `PY_RESUME`, and `PY_THROW`; ensure installer wiring respects the expanded mask; document the call/return mapping in `design-001`.
21+
- **Status:** _Completed_
22+
- `RuntimeTracer::interest` now subscribes to the four additional events plus `LINE`.
23+
- `design-docs/design-001.md` documents the call vs return mapping and clarifies how each event is encoded.
24+
- Verification: `just test codetracer-python-recorder --all-targets` (passes).
25+
26+
### WS2 – Call/Return Edge Helpers
27+
- **Status:** Not started (awaiting WS1 completion).
28+
29+
### WS3 – Activation & Lifecycle Behaviour
30+
- **Status:** Not started.
31+
32+
### WS4 – Testing & Validation
33+
- **Status:** Not started.
34+
35+
## Next Checkpoints
36+
1. Modify `RuntimeTracer::interest` and related tests to assert the expanded mask.
37+
2. Update `design-docs/design-001.md` to document the event-to-writer mapping.
38+
3. Capture verification notes (e.g., `just test codetracer-python-recorder --all-targets`) once WS1 lands.

design-docs/design-001.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,14 @@ allowing tracers to implement just the methods they care about.
157157

158158
Each bullet below represents a low-level operation translating a single `sys.monitoring` event into the `runtime_tracing` stream.
159159

160+
To keep the trace stack balanced we subscribe to `PY_START`, `PY_RESUME`, `PY_RETURN`, `PY_YIELD`, `PY_UNWIND`, `PY_THROW`, and `LINE`. `PY_START`/`PY_RESUME`/`PY_THROW` map to `TraceWriter::register_call`, while `PY_RETURN`/`PY_YIELD`/`PY_UNWIND` map to `TraceWriter::register_return`.
161+
160162
### Control Flow
161163
- **PY_START** – Create a `Function` event for the code object and push a new activation ID onto the thread's stack.
162164
```rs
163165
pub fn on_py_start(code: PyObject, instruction_offset: i32);
164166
```
165-
- **PY_RESUME** – Emit an `Event` log noting resumption and update the current activation's state.
167+
- **PY_RESUME** – Emit `TraceWriter::register_call` for the suspended activation (empty argument vector; CPython does not expose the `send()` payload) and update the current activation's state.
166168
```rs
167169
pub fn on_py_resume(code: PyObject, instruction_offset: i32);
168170
```
@@ -171,19 +173,19 @@ Each bullet below represents a low-level operation translating a single `sys.mon
171173
pub struct ReturnRecord { pub activation: ActivationId, pub value: Option<ValueRecord> }
172174
pub fn on_py_return(code: PyObject, instruction_offset: i32, retval: *mut PyObject);
173175
```
174-
- **PY_YIELD**Record a `Return` event flagged as a yield and keep the activation on the stack for later resumes.
176+
- **PY_YIELD**Call `TraceWriter::register_return` with the yielded value (subject to value-capture policy), mark it as a yield, and keep the activation on the stack for later resumes.
175177
```rs
176178
pub fn on_py_yield(code: PyObject, instruction_offset: i32, retval: *mut PyObject);
177179
```
178180
- **STOP_ITERATION** – Emit an `Event` indicating iteration exhaustion for the current activation.
179181
```rs
180182
pub fn on_stop_iteration(code: PyObject, instruction_offset: i32, exception: *mut PyObject);
181183
```
182-
- **PY_UNWIND**Mark the beginning of stack unwinding and note the target handler in an `Event`.
184+
- **PY_UNWIND**Treat as a return edge by calling `TraceWriter::register_return` with the active exception so the activation closes even when an exception propagates.
183185
```rs
184186
pub fn on_py_unwind(code: PyObject, instruction_offset: i32, exception: *mut PyObject);
185187
```
186-
- **PY_THROW** – Emit an `Event` describing the thrown value and the target generator/coroutine.
188+
- **PY_THROW** – Emit `TraceWriter::register_call` for the resumed activation and include a single argument named `exception` whose value is the thrown object.
187189
```rs
188190
pub fn on_py_throw(code: PyObject, instruction_offset: i32, exception: *mut PyObject);
189191
```

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)