fix(profiling): reject inconsistent Python 3.14+ asyncio task lists - #19798
fix(profiling): reject inconsistent Python 3.14+ asyncio task lists#19798taegyunkim wants to merge 9 commits into
Conversation
Codeowners resolved asResolved from the full PR diff against |
Circular import analysis
|
Dependency direction analysis
|
cee7a89 to
d345d83
Compare
d345d83 to
e7c8caf
Compare
🎉 All green!🧪 All tests passed 🔗 Commit SHA: dc5090f | Docs | View more details | Give us feedback! |
KowalskiThomas
left a comment
There was a problem hiding this comment.
Will continue reviewing later.
Co-authored-by: Thomas Kowalski <thomas.kowalski@datadoghq.com>
Co-authored-by: Thomas Kowalski <thomas.kowalski@datadoghq.com>
|
@codex review |
There was a problem hiding this comment.
Pull request overview
Hardens Python 3.14+ asyncio task discovery against inconsistent lock-free snapshots and duplicate task accounting.
Changes:
- Validates linked-list structure and rolls back failed-source results.
- Deduplicates tasks across discovery sources.
- Adds native regression coverage and a release note.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
releasenotes/notes/fix-profiler-asyncio-task-traversal-754a147329fc90cd.yaml |
Documents the profiling fix. |
ddtrace/internal/datadog/profiling/stack/test/test_task_traversal.cpp |
Tests stale-list rejection and deduplication. |
ddtrace/internal/datadog/profiling/stack/test/CMakeLists.txt |
Registers the native test. |
ddtrace/internal/datadog/profiling/stack/src/echion/threads.cc |
Adds validation, rollback, and deduplication. |
ddtrace/internal/datadog/profiling/stack/echion/echion/threads.h |
Grants the test fixture private access. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Codex Review: Didn't find any major issues. Swish! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Description
Python 3.14 tracks asyncio tasks in circular linked lists and can move a lingering task from a thread-local list to an interpreter-wide list. Echion samples these lists without acquiring the GIL or stopping Python threads, so it can observe the old thread-list head after the task has moved. Following that stale head enters the interpreter list at the moved task and repeatedly walks the same cycle. In the observed failure, Echion emitted one task 32,768 times before reaching its traversal limit, inflating task wall time and consuming significant profiler CPU.
This change rejects a task source when its links are inconsistent or a node repeats, discarding any tasks already collected from that source. It also deduplicates task identities found across the thread-local, interpreter-wide, scheduled, and eager task sources before accounting and reservoir sampling.
Testing
e7c8caf2e4d4dc14cf3bf2e91b4635bb9c670e2eto the Python 3.14 Rapid Test Drivepy314-echion-tasksas versionv132205293-daa67e1. The pod stayed healthy with no restarts while the standard Rapid Python smoke workload, including dynamic code generation, ran.unwind_tasks(),get_all_tasks(), andget_tasks_from_linked_list()together accounted for 27.4 ms/min, or 0.065% of native CPU.Risks
Normal Python 3.14 task-list traversal now performs one visited-set insertion per task, plus final cross-source deduplication. Typical task lists are small. Inconsistent lock-free snapshots fail closed for only the affected source, while discovery continues with other task sources as before.
Additional Notes
This issue was discovered while testing the Python 3.14+ Echion code-object cache invalidation work in #19641. The task traversal bug predates that PR and also reproduces from its merge base.
The reproducer was committed separately before the fix as
369097c3f. The Python 3.14 task-source roles, traversal validity conditions, earliest-snapshot deduplication policy, and source-local rollback contract are documented next to their implementations. The regression test also documents its synthetic list topology and restoration of CPython-owned links.