Skip to content

Commit b51740f

Browse files
committed
TASK-200: Retain probe readers through retirement and validate teardown repair
Close the test interposition stale-reader lifetime defect with retained publication ownership and a deterministic unrelated-reader retirement regression. Preserve the executor notification repair, public borrowing and cancellation contracts, and all three original RED discriminators. Record recovery proof and refreshed source, configuration, sanitizer and installed-consumer identities while preserving historical evidence. All eight applicable review domains approve, including seven focused closure reviews. Verify 66 focused program runs across normal, ASan/nonrecovering UBSan and TSan with TLS off/on, 18 installed-consumer runs, skip-exit checks, cpplint and the full diff whitespace check. No unexecuted findings remain. Nonlocal platform checks remain CI/v3-PR owned.
1 parent 71baf5d commit b51740f

6 files changed

Lines changed: 1274 additions & 22 deletions

‎specs/architecture/v3/TASK-200-implementation-evidence.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# TASK-200 implementation evidence
22

3+
Validation recovery subsequently repaired the test probe's reader lifetime; see
4+
[recovery evidence](TASK-200-recovery-evidence.md) and the
5+
[recovery receipt](TASK-200-recovery-receipt.json) for current source identities,
6+
the deterministic cleanup regression, and six passing local lane reruns. The
7+
implementation results below are historical. Runner validation retry is pending.
8+
39
TASK-200 is ready for caller-owned Groundwork validation/finalization. Its card and the global index remain **In Progress**. No commit, staging, validation agent, merge, worktree operation or TASK-185 edit was performed during implementation.
410

511
Registered runner identity: `/home/etr/progs/libhttpserver/.worktrees/TASK-200`, `task/TASK-200`, base `v3` at `4604fa2fcd29ea32f7fd62fbdf21ee15d7f217ee`. The starting worktree was clean and registered on that branch, at the same commit as `v3`. The identity helper invoked inside this checkout proposed a nested worktree; the primary checkout helper requested monorepo selection. The caller's explicit registered identity took precedence; neither helper result caused a workspace change.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# TASK-200 validation recovery
2+
3+
The critical fixture-lifetime finding is locally repaired. The runner must retry
4+
validation; this record does not claim review approval or task completion. TASK-200
5+
remains In Progress on `task/TASK-200`. Changes are unstaged and uncommitted for the
6+
runner-owned commit flow. No Groundwork skill, publication, merge, or next lifecycle
7+
step was invoked.
8+
9+
## Cause and repair
10+
11+
`manual_executor_post_probe.hpp` previously published a raw pointer to stack
12+
storage. Every intercepted mutex unlock read that pointer before deciding whether
13+
its mutex matched. An unrelated timer-service reader could retain it beyond the
14+
owner's deactivation and scope exit. A serial timer callback promise acknowledges
15+
earlier callback processing, but does not retire every unrelated wrapper reader.
16+
17+
Discovery now uses C++20 `atomic<shared_ptr<publication>>`. Each wrapper holds a
18+
strong reference before its first dereference. The thread-local producer also
19+
holds a strong reference across the post tail and notification wrapper; the
20+
existing joined-thread and serial-timer cleanup paths clear it. The capture
21+
pointer remains confined to its owner's synchronous mutex-discovery call and is
22+
cleared before publishing the initialized probe. Probe mutex identity and owner
23+
are immutable after publication, and the remaining shared fields are atomic.
24+
25+
The local libstdc++ implementation in
26+
`/usr/include/c++/13/bits/shared_ptr_atomic.h` uses an atomic reference-count lock
27+
bit for shared-pointer load/store. Its unlock uses atomic operations, and its
28+
spin relaxation uses processor pause or scheduler yield
29+
(`bits/atomic_wait.h`). These operations do not recursively call the wrapped
30+
pthread mutex unlock. Both TSan lanes execute this protocol without diagnostics.
31+
The helper is enabled only for the existing Linux/libstdc++ interposition target.
32+
No production code, API, executor ownership contract, or suppression changed.
33+
34+
## Deterministic regression and preserved production discriminator
35+
36+
`probe_lookup_retains_retired_publication` arms a reader-local gate immediately
37+
after wrapper discovery and before its first publication dereference. The reader
38+
unlocks an unrelated mutex; while it is paused, the owner clears discovery and
39+
drops its last strong reference. A weak reference proves the reader still owns
40+
the publication. The fixture then releases and joins the reader and proves the
41+
publication has been destroyed. Assertions follow thread cleanup, and the gate
42+
storage remains alive through the join. Bounded waits diagnose stalled progress;
43+
no sleep, retry, grace interval, or sanitizer suppression supplies ordering.
44+
45+
| Check | Exit | Cases / checks / failures / skips |
46+
| --- | --- | --- |
47+
| Reported bounded audit reproducer with raw stack discovery | 1 | ASan stack-use-after-return at its first dereference |
48+
| New regression with raw discovery, ASan/UBSan | 1 | 3 / 39 / 1 / 0; retained-ownership assertion fails |
49+
| Repaired fixture, ASan/nonrecovering UBSan | 0 | 3 / 39 / 0 / 0 |
50+
| Repaired fixture against unchanged base executor | 3 | 3 / 39 / 3 / 0; exactly the original timeout, signal, and cancellation late-notification failures |
51+
52+
The new RED assertion uses a weak reference to observe retirement deterministically.
53+
The weak reference keeps the allocation's control block available, so that RED
54+
is a behavioral lifetime failure, not a claim of a second ASan memory diagnostic.
55+
The separately reproduced original stack case confirms the unsafe dereference.
56+
An initial sandboxed RED execution also reported the ptrace LeakSanitizer
57+
limitation; the retained RED receipt is the subsequent outside-ptrace execution
58+
with leak checks enabled. Sanitizers and existing suppression inputs were kept
59+
unchanged.
60+
61+
## Local verification
62+
63+
All six existing configured lanes rebuilt `task_race` and reran the eleven focused
64+
programs, staged public headers, compiled and executed the three installed
65+
consumers, and passed the Littletest skip-exit gate. Toolchain is Ubuntu clang
66+
18.1.3, C++20. Commands and environments are in the
67+
[recovery receipt](TASK-200-recovery-receipt.json), including log, binary, and
68+
current source hashes. Recovery artifacts and copies of the latest per-test logs
69+
are under `build/task200-recovery/`; the configured implementation build trees
70+
were reused. The tracked original implementation receipt remains historical;
71+
its per-test paths in the reused trees now contain the recovery runs.
72+
73+
| Lane | Programs | Harness cases / checks / skips | task_race cases / checks / skips | Installed consumers |
74+
| --- | --- | --- | --- | --- |
75+
| normal-off | 11/11 | 60 / 5823 / 0 | 7 / 2041 / 0 | 3/3 |
76+
| normal-on | 11/11 | 60 / 5823 / 0 | 7 / 2041 / 0 | 3/3 |
77+
| asan-ubsan-off | 11/11 | 60 / 5823 / 0 | 7 / 2041 / 0 | 3/3 |
78+
| asan-ubsan-on | 11/11 | 60 / 5823 / 0 | 7 / 2041 / 0 | 3/3 |
79+
| tsan-off | 11/11 | 60 / 5811 / 1 | 7 / 2041 / 0 | 3/3 |
80+
| tsan-on | 11/11 | 60 / 5811 / 1 | 7 / 2041 / 0 | 3/3 |
81+
82+
All steps exit 0. The existing TSan allocator-interposition case remains the sole
83+
skip in each TSan lane; the new cleanup case and both production regressions run
84+
without skips. ASan leak/stack checks and nonrecovering UBSan run outside ptrace.
85+
`cpplint` for both changed C++ files and `git diff --check` pass. Suppression SHA-256
86+
remains `bef8512659b644216f9b4ad3640fd77cf911a11c3e9899f8f5ff36b32f7aee85`.
87+
Nonlocal platform evidence remains CI/v3-PR owned under AGENTS.md.

0 commit comments

Comments
 (0)