Repository navigation
Upstream defects register (clangd, mcpp) #24
Copy link
Copy link
Open
Description
Register of upstream defects mcppls depends on. This body is the index; each comment below is one problem.
Bundled: clangd 23.1.0 (clangd/clangd release). Code workarounds: src/engine/clangd/workarounds.cpp (WA-CLANGD-<n>, listed by mcppls report); deliberate limits: .agents/docs/design.md §7.
Rules: a new problem gets a comment and a row here; adding or removing a workaround updates its comment; link upstream issues/fixes when they exist; walk this list before bumping the bundled clangd.
clangd / LLVM
| ID | Problem | Upstream | mcppls |
|---|---|---|---|
| UP-01 | Module name ending in . hangs the preprocessor (crashes on Windows) |
unfiled; fixed on main? (deferred) | WA-CLANGD-001; disk check (0.0.5) |
| UP-02 | Unresolved import can deadlock the unit's build | unfiled | WA-CLANGD-002; disk check (0.0.5) |
| UP-03 | Modules a file needs are built one at a time | unfiled (perf) | WA-CLANGD-003 |
| UP-04 | Finding a module's unit scans the whole database | unfiled (perf) | WA-CLANGD-004 |
| UP-05 | MSVC STL aligned allocation rejected (align_val_t ambiguous) |
fixed in 23.1.1 (llvm-project#218152) | WA-CLANGD-005 |
| UP-06 | Stops answering one file while answering others | unfiled | quarantine |
| UP-07 | Stuck with no CPU after rapid module edits | unfiled | StuckWatch restart |
| UP-08 | Background index does not build module imports (definitions indexed apart from their declarations) | unfiled (gap); cf. clangd/clangd#2569 | WA-CLANGD-008: implementation units built in the foreground; search by name (0.0.6) |
| UP-09 | No textDocument/semanticTokens/range |
unfiled (gap) | capability gated |
| UP-10 | import std; then an unprovided export import never finishes |
unfiled | known limit |
| UP-11 | Module scanning fails on link-phase driver errors | unfiled | fixed in mcppls 0.0.5 (-c) |
| UP-12 | Windows: Build AST crash on a module unit with unresolved imports | unfiled; needs stack | avoided by -c; crash file set aside (0.0.5) |
| UP-13 | Windows: Build AST crash on some units even with correct commands | unfiled; needs stack (Windows release prints none) | contained (0.0.5); crash records carry clangd's SHA-256 (0.0.8) |
| UP-14 | Imports added in an unsaved buffer are not built until save | unfiled | WA-CLANGD-007; disk check (0.0.5) |
| UP-15 | Missing ; after import is reported on the next line |
unfiled | WA-CLANGD-006 (0.0.5) |
| UP-16 | C++26 contracts and reflection are not implemented | gap (upstream work in progress) | documented; VS Code colors contract keywords |
| UP-17 | A function defined in an open unit is missing from the index (prepare_build) |
unfiled; not reduced yet | definition found by name (0.0.6) |
| UP-18 | A module lock left by a killed clangd is never released (Windows waits forever) | unfiled | locks cleared at start and on a wait (0.0.7) |
| UP-19 | One BMI directory per command, never removed | unfiled (gap) | two newest kept, mcppls cache --prune (0.0.7) |
| UP-20 | Crash loop on a fan-out save of mcpp.manifest.types |
unfiled; needs a stack | backed off, bundle written (0.0.7); crash records carry LLVM's stack dump and clangd's SHA-256 (0.0.8, K-3) |
| UP-21 | A unit closed while its build runs can keep a worker spinning | unfiled | K-8 restart (0.0.8); K-7 |
| UP-22 | clang-tidy: misc-const-correctness says a filter/drop_while/chunk_by/split view can be const (issue #37) |
unfiled; reduced case ready | WA-CLANGD-010 drops it (0.0.9) |
| UP-23 | --experimental-modules-support rescans module dependencies on every completion (~3x slower on heavy headers, issue #37) |
unfiled (perf) | WA-CLANGD-009: off for projects without modules (0.0.9) |
| UP-25 | Every completion on a file that imports modules costs ~1 s, even unchanged (the module context is re-loaded per request; a file without imports in the same project: 60 ms) | unfiled (perf) | WA-CLANGD-012: the file's budget extends past the flat one when the engine's answers keep landing just past it (0.0.11, PR #41) |
| UP-26 | Preamble trace filename metadata can outlive borrowed storage and corrupt trace JSON | unfiled; pinned 23.1.0 source-backed | proposed maintained patch0051 owns metadata; delayed-context/native canaries pending |
| UP-27 | Default OverlayCDB invokes a null command mangler during module scanning | unfiled; 23.1.0 source/API control confirmed | maintained engine0058 pending; no product workaround |
| UP-28 | Header-import PCH visibility guard reparses heavy textual prefixes | llvm-project#181770; mitigation#189284 | conservative handling retained; verified import-free prefix candidate0066 pending |
| UP-29 | GNU std producer flags enable Clang implicit builtin maps during scanning | unfiled; pinned23.1.0/GNU16.1 source evidence | scoped same-install standard-producer adapter candidate0067 pending |
| UP-30 | One prerequisite module that does not compile leaves its importers with no module at all | unfiled | WA-CLANGD-014 (importers to mcppls's engine); mcppls-clangd 0.0.13 0028 (partial-prerequisite-modules) retires it |
| UP-31 | Completion in a module importer waits without bound for its first preamble and new imports | unfiled | mcppls-clangd 0.0.13 0027 (bounded-module-wait): 600 ms / 250 ms, answers marked incomplete |
| UP-32 | Why a module is rebuilt, and what a file's prerequisites cost, is not logged at the default level | unfiled (observability) | mcppls-clangd 0.0.13 0026 (module-rebuild-reasons); mcppls 0.0.13 startup line |
mcpp
| ID | Problem | Upstream | mcppls |
|---|---|---|---|
| UP-M1 | mcpp: macOS deployment target ignored when cross-compiling | fixed (mcpp#685, 2026.9.24.1) | done in 0.0.5 |
| UP-M2 | mcpp: emit build-database fails whole on one member's failure |
fixed (mcpp#699, 2026.9.26.2) | partial answer used; download offer for a missing member (0.0.6) |
| UP-M3 | mcpp: build programs cannot tell a plan/emit pass | filed: mcpp#699 | none |
| UP-M4 | mcpp: a rule's inputs are translation units; generated output points at an empty directory | filed: mcpp#724 | inputs left out; project's target/ read; missing reported (0.0.6) |
| UP-M5 | mcpp 2026.9.27.1: workspace = true in a path-dependency member fails |
filed: mcpp#725 | CI pins 2026.9.26.1 |
| UP-M6 | mcpp: emit build-database takes about a minute on a large workspace |
unfiled (perf) | deadline follows the producer; reruns only on structure changes (0.0.7) |
| UP-M7 | mcpp: a module source two packages include is reported as provided twice; the member is left out | unfiled | partial answer used; stand-ins together (0.0.8, P-1) |
PRoot (Termux)
| ID | Problem | Upstream | mcppls |
|---|---|---|---|
| UP-P1 | termux/proot: execveat with a directory descriptor fails with ENOSYS |
to be filed | openkal-linux 0.15.1 falls back to execve (0.0.7) |
| UP-P2 | seccomp mode returns with rewritten argument registers (termux, proot-me) | to be filed | argument registers declared in/out (0.0.7) |
| UP-24 | clangd leaves a copy-on-read BMI behind whenever it dies before releasing it; the only GC waits 3 days and reads atime (unreliable on Windows, and it removes published BMIs too) | 23.1.0 (bundled) | unfiled (recorded here) |
openkal
| ID | Problem | Upstream | mcppls |
|---|---|---|---|
| UP-O1 | openkal-macos 0.12.0 terminates a closed-pipe writer with SIGPIPE | unfiled | WA-PLATFORM-001: per-input-pipe protection; native fix validation pending |
VS Code / languageclient
| ID | Problem | Upstream | mcppls |
|---|---|---|---|
| UP-V1 | vscode-languageclient 10.1.1 loses startup ownership when the server exits during initialize; unhandled start/stop rejections | unfiled; standalone reproducer TODO | WA-VSCODE-003; queued fresh-client recovery; native macOS SIGPIPE cause remains unverified (0.0.12, PR #46) |
| UP-V2 | vscode-jsonrpc 9.0.2 throws from a discarded async request executor after a failed stream write | unfiled; deterministic Linux reproduction | WA-VSCODE-004; failed protocol writes close their connection; native Intel macOS revalidation pending (0.0.12, PR #46) |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
Sunrisepeak commentedon Sep 25, 2026
UP-01 · Module name ending in
.hangs clangd token collectionSymptom: in an
import/moduledirective, a name ending in.with nothing but whitespace or a comment after it on that line (everyimport a.bpasses throughimport a.) sends the preprocessor into a loop (P1857 directive lexing). Linux/macOS: never finishes. Windows: exits0x80000003. Also without--experimental-modules-support.Affected: clangd 23.1.0. 22.1.8 and main
510126255are fine.Upstream: unfiled. Likely fixed on main by
6dcfc17b1b(#187846), not in 23.1.2; not bisected.mcppls:
WA-CLANGD-001— the text sent to clangd gets a;after the dot on the same line (positions unchanged).Remove when: the bundled and the oldest supported clangd finish
import a.at once (canary:conformance/fixtures/workaround-canaries).Evidence:
.agents/docs/2026-09-25-import-hang-status-highlight.md§1; fixturestyping-import,typing-import-spin.Hole (2026-09-26, measured):
WA-CLANGD-001rewrites only the text sent over LSP. Withfiles.autoSave, the file on disk holdsimport hello.; clangd resolves prerequisite modules from the file on disk (UP-14), and the file'sWorker:<file>thread then spins at 100 % CPU (buffer only: 2 ticks / 20 s; on disk: ~2000). Fixing the buffer does not stop it; only a clangd restart does. Every request for that file waits behind it, so clangd-backed completion (keywords) and hover disappear, and repeated autosaves drive restarts into the cap. Fix plan F16.Decision (2026-09-26): mcppls first ships the disk-side mitigation (fix plan F16: isolate the file before clangd reads the half-typed name; restart only as a fallback). Upstream work is deferred — handled later; bundling a self-built 23.1.x with the fix cherry-picked is the fallback if no backport comes.
Shipped (mcppls 0.0.5): the disk side is covered: a file whose text on disk has such a name is set aside before clangd builds it, a build begun on it just before is let finish for 1.5 s or clangd is restarted without it, and the file goes back once the disk is fixed (fixture
typing-autosave; hello project: 0 CPU for every clangd thread over 20 s withimport hello.on disk).TODO (deferred): bisect (
6dcfc17b1b?), file, ask for a 23.1.x backport.Root-cause correction (2026-10-07): ordinary clang parsing terminates for
the same malformed input. A raw clangd --check debugger stack stops in
TokenCollector::consume during ParsedAST construction. Controlled temporary
instrumentation identifies logical tok::eod newline: it has no spelled C++
token, so token mapping reaches a nonprogress failure path. The earlier
preprocessor-loop diagnosis and proposed main commit were hypotheses, not
established root causes. Instrumentation was removed before the repair.
Maintained-engine repair: patch 0015 skips logical end-of-directive tokens
in collection. Local Linux raw clangd lit passes; six LSP variants reply,
recover after didChange, close/reopen and shut down. Two exact before-fix
controls time out. See engine PR Bump actions/cache from 4 to 6 #2 and tests/evidence/module-directive-recovery.json.
The syntax unit regression is added but not yet executed locally.
Remaining: final packaged-byte and native Windows proof, cancellation
and missing-provider hangs. WA-CLANGD-001 remains enabled; no unsupported
engine loses its mitigation. The fix is not upstream-submitted yet.
Sunrisepeak commentedon Sep 25, 2026
UP-02 · Unresolved import can deadlock the unit's build
importresolves to nothing can deadlock clangd.WA-CLANGD-002— such imports get an empty stand-in unit.module-faults.import hello.e(a module that does not exist yet), below a working import, stalls every request for the file — the stand-in the plan withheld while the name was typed never came. mcppls 0.0.5: the plan gives a file being edited a stand-in for every module its text on disk imports, the scanner counts an import whose;is not typed yet (as clang does), and a file whose disk imports the database clangd has read cannot resolve yet is set aside until it can (fixturetyping-autosave).Sunrisepeak commentedon Sep 25, 2026
UP-03 · Modules a file needs are built one at a time
WA-CLANGD-003— mcppls prepares the modules in parallel first (prime units).timing.Sunrisepeak commentedon Sep 25, 2026
UP-04 · Finding a module's unit scans the whole database
ProjectModules.cpp,CompileCommandsProjectModules).WA-CLANGD-004— the database names each unit (-fmodule-file=<name>=<path>,-fmodule-output=); clangd scans only that file to confirm.timing.Sunrisepeak commentedon Sep 25, 2026
UP-05 · MSVC STL aligned allocation rejected (
align_val_tambiguous)align_val_tis ambiguous inside itsstdmodule.WA-CLANGD-005— units using MSVC STL get-fno-aligned-allocation..agents/docs/design.md§7; fixturescmake-msvc-std,mcpp-msvc.Sunrisepeak commentedon Sep 25, 2026
UP-06 · Stops answering one file while answering others
Quarantine(src/engine/clangd/guard.cppm) — the file is set aside and answered by mcppls's own engine, handed back when it changes or its term ends.Sunrisepeak commentedon Sep 25, 2026
UP-07 · Stuck with no CPU after rapid module edits
StuckWatchrestarts it (docs/50-troubleshooting.md). Not detected on Windows, where clangd's CPU time is unreadable; files are set aside one by one instead.Sunrisepeak commentedon Sep 25, 2026
UP-08 · Background index does not build module imports
Failed to compile …, index may be incomplete(16 of 16 units of a small partitioned module;math.cppindexed with 0 symbols), and a definition whose signature uses a type from a module is indexed as a different symbol from its declaration (workspace/symbolreturns both). In mcpp's ownpreparemodule, go-to-definition onphase0_manifest_and_workspace(PrepareState&)stayed on its declaration for as long as it was measured (420 s). Opening the defining unit fixes it (the foreground builds its modules), and the symbols stay after it is closed.BackgroundIndex::index()inclang-tools-extra/clangd/index/Background.cppbuilds the compiler instance with no ModulesBuilder).mcppls.index.primeImplementationUnits), the search picks the units that define the name, and a definition clangd still cannot link is found by name (plan.agents/docs/2026-09-27-qt-demo-navigation-discovery-plan.md§2.3, N-7, N-8; fixturemcpp-partition-definition, which 0.0.5 fails).Sunrisepeak commentedon Sep 25, 2026
UP-09 · No
textDocument/semanticTokens/rangerangeonly when every engine can answer it (src/orchestrator/tokens.cppm).Sunrisepeak commentedon Sep 25, 2026
UP-10 ·
import std;then an unprovidedexport importnever finishesimport std;precedes anexport importof something nothing provides never finishes, when the command namesstd's unit (-fmodule-file=std=…). Minimal:export module m;import std;export import :p;.510126255..agents/docs/design.md§7): only stray files outside the database get such a command; the first-diagnostics guard sets them aside after 120 s.Sunrisepeak commentedon Sep 25, 2026
UP-11 · Module scanning fails on link-phase driver errors
ModuleDependencyScanner::scan→getP1689ModuleDependencyFile) runs the command as written and fails onCompilation->containsError(), while AST building (createInvocation) inserts-fsyntax-only. A driver error that only exists for a link (e.g.LTO requires -fuse-ld=lldfor windows-msvc with-fltoand no-c) fails every scan: no BMI is built, yet ASTs look fine.-c). Fixed in 0.0.5: every engine command carries-c(fixturecompdb-lto-msvc); a scan that still fails on a command is told as an environment issue with the driver's words (fixturecompdb-rejected-command).clang/lib/Driver/Driver.cpp(err_drv_lto_without_lld),clang/lib/Tooling/DependencyScanningTool.cpp:121; reproduced locally and in GalTranslPP CI (run 36178100611).Sunrisepeak commentedon Sep 25, 2026
UP-12 · Windows: Build AST crash on a module unit with unresolved imports
Symptom: on Windows, Build AST of a module unit whose imports cannot resolve (no BMIs) crashes,
0x80000003. Example: GalTranslPPGPPDefines.ixx(onlyexport imports and declarations).Affected: clangd 23.1.0 (clangd/clangd Windows release). Same input does not crash on Linux.
Upstream: unfiled — needs a stack and a minimal repro.
mcppls: triggered by UP-11; with
-cthe BMIs build and the crash is gone (--check: crash as written, exit 0 with-c). Fix plan F1, plus precise quarantine from clangd's crash context (F3).Evidence: GalTranslPP CI run 36178100611, experiments E3a/E3b/E3c.
Notes: clangd prints only
Signalled during AST worker action: Build AST,Filename:andException Code: 0x80000003; no stack, no minidump, no event-log entry. Same code as UP-01 on Windows. UTF-8 BOM is not the common factor.TODO: stack via the SDK's
cdb.exein that CI; compare clangd 22.1.8; reduce; file.Native source-qualified maintained proof (2026-10-08): Windows workflow37722679744 at engine source9e0e535191 passes the qualified nonempty original GalTranslPP case, retaining six missing BMI hints, original stdc++23/O3/g/flto flags and missing-c shape. Matching clangdSHA86468960e2a4f237f9012b3db2383ce9dd0b5d5e156dad74a3bff3f1a84539ad has PDBGUID{A440DF1E-E48C-4BB9-AC86-A1A1D219585E}/age1; debugger symbol lookup of clangdMain succeeds. Replay exits0, readers stop and actual documentSymbol result includes NameType/kind10. Engine draftPR2 tracks
tests/evidence/windows-up12-fixed-fork.jsonand qualification documentation. This proof covers that source only; final joint patches must replay the corpus again. UP13/UP20 and final native release remain unqualified.Sunrisepeak commentedon Sep 25, 2026
UP-13 · Windows: Build AST crash on some units even with correct commands
NormalJsonTranslator.Core.cpp(global module fragment including pybind11/toml11/proxy, thenmodule X;and severalimports) crashes,0x80000003, even with-c, working BMIs and cross-module hover.clangd-crash-context), clangd waits for the build tool's model instead of crashing on a provisional one, and a provisional model's crashes are forgotten when it is replaced.NormalJsonTranslator.{Batch,Core,File}.cpp,.ixx, Build AST,0x80000003) — the files' own builds, not preparation, which 0.0.8 no longer does on a provisional model (R-4) — and five more after a partial model from mcpp (UP-M7) replaced it. mcppls 0.0.8 records each crash's exit code and the clangd binary's SHA-256 inlastExitand the incident (K-3): heredbd52c13d21ef9d284f4f0627efe76c81adf2fe0998f230127f554a54fc9dde7(clangd 23.1.0, clangd/clangd Windows release). The Windows release printsException Code:and no stack frames, so there is still no stack to report.Sunrisepeak commentedon Sep 25, 2026
UP-M1 · mcpp: macOS deployment target ignored when cross-compiling
macos_deployment_target(alwaysminos 14.0); users on macOS 11–13 cannot launch the server.macos_deployment_target = "11.0",minos 11.0verified.19 remaining items
Sunrisepeak commentedon Oct 1, 2026
UP-23 · clangd 23.1: with
--experimental-modules-support, every completion scans the file's module dependencies againconstness #37), completion is about 3 times slower with the flag than without it.Measured on 12 completions (
phy_device.,vk::,memory_properties.,std::ranges::), median and worst:The other mcppls flags (
--use-dirty-headers,--header-insertion=never,-j=8) change nothing.With the flag, clangd's verbose log shows one more driver invocation per completion: 25 against 13 for the same session. That is a dependency scan, which preprocesses the whole translation unit, vulkan.hpp included, on every request.
--experimental-modules-supportfor a project whose plan has no module unit, no module import, no standard library module and no stand-in..agents/docs/reviews/2026-10-01-issue-37-review.md§B (bench script and numbers).Sunrisepeak commentedon Oct 2, 2026
UP-24 · [clangd] a copy-on-read BMI is left behind whenever clangd dies before releasing it, and the only GC waits three days (by atime)
Labels:
clangd,clang:modulesSymptom. When clangd reuses a published BMI it first copies it to a timestamped sibling
(
<module>-YYYYMMDD-HHMMSS-<serial>.pcm) and hands that copy to clang; the copy is removed only in the owner'sdestructor (
ModulesBuilder.cpp23.1.0 §198-209, §437-461). A clangd that is killed by a crash never runs it, sothe copy stays. One real workspace (Windows 11, MSVC STL, 23.1.0) after 26.5 h: 64.36 GiB, 6837
.pcmfor 48module units, where one file per unit×command directory is 2.03 GB (2.9%) — 97.1% leftovers, up to 127
copies in one directory, 219 retained "clangd exited unexpectedly" lines (≈305 MB leaked per crash). Three sampled
copies of
pybind11were byte-identical (39,639,212 bytes; SHA-2565d0b9efe…9289ab) with distinct ids — copies,not rebuilds, and not hard links.
Affected. 23.1.0 (persistent cache + copy-on-read + the 3-day atime GC). 22.x uses a per-process temp layout.
Upstream status.
unfiledhere (mcppls does not file; recorded in the mcppls register). The GC exists(llvm/llvm-project#193973, merged to main 2026-04-24) and is the intended answer, but: (1) a crash leaks and the
window is 259200 s, so peak ≈ leak rate × 3 days; (2) it reads
st_atime— the PR body notes atime is unreliableon some systems, and NTFS last-access updates are off by default, so a copy still mapped by a live clangd can be
selected and the removal fails with a sharing violation (only logged); (3) the option's description says "versioned
copy-on-read module files" while
collectModuleFiles()takes every.pcmunder the cache root, so lowering thethreshold also deletes published BMIs (the cost becomes rebuilding 30–40 MB modules, not re-copying them).
What mcppls does (workaround).
WA-CLANGD-011. mcppls owns<cdb>/.cache/clangd(it already clears.locksthere before clangd starts, RD12) and extends that to the copies: before each clangd start, and for every workspace
no instance has open, it removes files whose name parses as the versioned shape, keeping the published
<module>.pcm, in the background and only for files older than the new generation's start; it also enforces asize budget per workspace (4 GiB) and in all (16 GiB), reclaims orphaned per-instance cache directories, and shows
the whole thing in the editor status bar with a one-click sweep. Design: PR #39 /
.agents/docs/2026-10-02-cache-growth-root-fix-plan.md(C-7, C-8, C-9, C-13). mcppls deliberately does not lower--modules-builder-versioned-gc-threshold-secondsby default (point 3).When that can go. When the bundled clangd leaves no copy-on-read file behind after a process dies, or removes an
earlier clangd's leftovers of the same cache root within minutes without touching the published BMI. Canary:
conformance/fixtures/cache-budget+tests/test_cache.cpp— the sweep's semantics are asserted on every run;a real-crash canary needs the crash-symbol work of the 0.0.7 plan (T15/K-3).
Evidence.
mcppls-cache-20261002-222834.zip+.agents/reviews/mcppls-cache-20261002-cause-analysis.md;ModulesBuilder.cppofllvmorg-23.1.0§40-44/§198-209/§437-461/§986-1018; #193973.TODO. [x] post this comment and add its row to #24's index
[x] put the link in
WA-CLANGD-011.upstream[ ] attach a minimal reproduction once the crash-symbol work of the 0.0.7 plan (T15/K-3) lands.
mcpp-language-server 0.0.10: the module cache is bounded, visible, an…
Sunrisepeak commentedon Oct 3, 2026
UP-25 · clangd 23.1: every completion on a file that imports modules costs about a second, even on an unchanged document
Labels:
clangd,clang:modulesSymptom: a project that uses modules (qt-demo: Qt 6.11 headers,
import std;+import nlohmann.json;, gcc 16 / libstdc++, the mcppls-generated CDB); the bundled clangd 23.1.0 driven directly over stdio, mcppls out of the picture — these numbers are clangd's alone. Keystroke replay at the importer (nlohmann::j, thennlohmann::js), three rounds, plus re-asks on an unchanged document:j(3 rounds)jsonpresents(3 rounds)cli.(a Qt member) and a plain word in the same importing file: 977–1033 ms.moc_counter.cpp, same project, same CDB, same flags (--experimental-modules-supportincluded), no module imports: 60–65 ms for the same replay — 16×.std.pcm35 MB andnlohmann.json.pcm25 MB under<cdb>/.cache/clangd/modules, "Reusing persistent module …" in the log), so the cost is not building them: each AST build re-loads the module context ("Built prerequisite modules … in 0.53 s"), and the importer's preamble is 254 KB built in 0.01 s — the imports are not in it, so nothing between requests amortizes the module state. Typing bursts cancel each request before it finishes, which reads in the editor as "completion does not come up".Affected: clangd 23.1.0 (bundled), Linux x64; any file that imports modules whose BMIs are already built and cached. Distinct from UP-23: that one is the flag's cost on a project without modules; this one is the cost on a file that actually imports, with everything already built.
Upstream: unfiled (performance). A completion on an unchanged document should reuse the module context of the cached AST; an importing file's preamble cannot carry the imports, but the per-request BMI re-load looks avoidable.
mcppls: WA-CLANGD-012 (0.0.11, PR 0.0.11: the completion budget follows the file, so clangd's ~1 s module-importer answers are not cancelled (UP-25) #41). The flat completion budget stays 1000 ms; the workspace records each core-engine completion answer per file and its latency (the late answers C-2 keeps included), and where two answers in the last ten seconds have all landed past the flat budget, that file's completion and signature-help budget extends to their slowest plus 500 ms, 2.5 s at most — the importer's ~1 s answers arrive instead of being cancelled at the line. An engine that answers rarely (a broken module rebuilding, a fan-out save) or quickly keeps the flat budget, and the fallback with it. A flat 1.5 s budget was tried first and the UX gate rejected it with data (U16-module-autosave: 93 completions p95 1.50 s, every one riding to the budget; ux-xlings and ux-mcpp failed, CI run 37188779178) — a flat constant cannot hold both regimes.
Evidence: LSP replay probe against the bundled clangd with the workspace CDB (2026-10-04); clangd verbose log (preamble size and time, "Reusing persistent module", "Built prerequisite modules", one "ASTWorker building file … version N" per keystroke).
TODO:
mcpp-language-server 0.0.11: completion comes up in files that import…
Sunrisepeak commentedon Oct 7, 2026
UP-O1 · openkal-macos 0.12.0 can terminate a pipe writer with SIGPIPE
Sunrisepeak commentedon Oct 7, 2026
UP-V1 · vscode-languageclient loses initialization ownership when its server exits during startup
Affected: vscode-languageclient 10.1.1 (the extension lockfile); reproduced with VS Code 1.132.0 on Linux. Product CI run 37658653689 on Intel macOS also reports duplicate
clangd.applyFix, disposed pending responses andUnexpected SIGPIPEduring the crash-loop test, but this entry does not claim that SIGPIPE has the same root cause.Symptom and evidence: SIGKILL the replacement server while client initialization is pending. With the original extension and the new real-payload regression, the suite produces 1 passing / 2 failing tests and captures four unhandled rejections: two pending responses disposed, two stop attempts on a Starting client. The guarded lifecycle produces 2 passing tests and zero captured unhandled rejections, and verifies command registration plus a cache request after recovery. Detailed proof, intermediate failures and limits:
.agents/docs/2026-10-08-client-crash-recovery.mdin draft PR #46.Source:
vscode-languageclient/lib/common/client.js10.1.1:start()owns a separate internal_onStartpromise;handleConnectionClosed()disposes the connection and resets it before the original initialization continuation necessarily settles;doInitialize()callsvoid stop()on failure, which rejects for a dead Starting client. Same-client automatic restart can additionally overlap feature cleanup/initialization. The macOS duplicate-command explanation is source-supported inference, not the exact stack reproduced on Linux.Upstream status: unfiled. A standalone library reproducer and upstream review remain TODO; no upstream fix is known or claimed by this entry.
mcppls: WA-VSCODE-003 in
editors/vscode/src/workarounds.tsandextension.ts. Wait for original startup settlement in the close handler before library cleanup/reset; absorb a failed shutdown only after that client's transport closes. The extension queues fresh-client recovery, preserves the three-crash budget, and skips conflict-detection prompts during automatic recovery.Remove when: an updated upstream library passes the initialization SIGKILL test with the guards removed: no orphaned start promise, no unhandled shutdown rejection, working command registration and requests after recovery.
test/suite/zCrashLoop.test.tsis the behavioral regression; run the unguarded negative control when evaluating a dependency upgrade.TODO: standalone reproducer, upstream filing, inspect any upstream lifecycle fix before removing WA-VSCODE-003, rerun the native Intel macOS VSIX scenario and separately establish the SIGPIPE cause.
Sunrisepeak commentedon Oct 7, 2026
UP-V2 · vscode-jsonrpc leaves a failed request write's async executor rejection unowned
Affected: vscode-jsonrpc 9.0.2, used by vscode-languageclient 10.1.1 in the extension lockfile. Reproduced on Linux with the actual dependency and a destroyed Node stream. Product CI run 37686772481 reports two unhandled
ERR_STREAM_DESTROYEDrejections in the Intel macOS VSIX crash-loop suite after the UP-V1 lifecycle guard was present.Symptom and evidence: A correctly caught
sendRequest()still emits an independent unhandled rejection when its stream write fails. The caller receivesMessageWriteError(-32099), while the process separately receivesERR_STREAM_DESTROYED. Source:vscode-jsonrpc/lib/common/connection.js,sendRequest()lines 1124–1151: an async Promise executor awaits the write, rejects the caller in its catch, then throws the same error into the executor's discarded promise. The CI stack starts in Node_write, thenWritableStreamWrapper.write,StreamMessageWriter.doWrite; the crash-loop after-all assertion catches two orphaned rejections. This source defect is directly reproduced; the CI stack alone does not identify each original request.Upstream status: unfiled. A standalone upstream issue and dependency upgrade evaluation remain TODO.
mcppls: WA-VSCODE-004, a writer scoped to each LanguageClient transport. A failed write invalidates that protocol stream and raises connection closure; normal connection disposal rejects outstanding requests. The wrapper owns the failed write promise rather than allowing the library's discarded executor to throw. There is no process-wide rejection handler in production. Live responses and server request errors remain unchanged. A deterministic Linux regression receives the normal disposed-request error (-32097), observes no orphaned rejection, and checks a live response plus a real server error.
Remove when: a dependency upgrade passes the failed-stdio-write regression without the writer wrapper: the request rejects once, no independent unhandled rejection, normal responses and server errors still work.
editors/vscode/test/unit/transportWriter.test.tsand the real-payloadtest/suite/zCrashLoop.test.tscover those behaviors. Native Intel macOS revalidation remains required; Linux controlled evidence is not a native verdict.TODO: standalone upstream filing, rerun the native Intel macOS VSIX crash-loop suite, inspect the upstream sendRequest implementation before retiring WA-VSCODE-004.
Sunrisepeak commentedon Oct 8, 2026
UP-26 — asynchronous preamble trace metadata outlives its filename
Symptom:
BuildPreambletraceargs.Filecontains freed-looking bytes and can make the trace JSON invalid UTF-8. This is observed diagnostic corruption; it is not evidence of a semantic compiler crash.Affected: the pinned LLVM/clangd 23.1.0 baseline borrows
FileNameatPreamble.cpp'sBuildPreambleandCreatePreamblePatchspans.json::Value(StringRef)retains borrowed storage, whileJSONSpancan remain alive through a retained requestContextafter the lexical span and filename owner end. Other upstream versions are untested.Upstream status: unfiled; deterministic old/fixed Linux regression is complete; native/full-recipe qualification remains pending.
What mcppls does: maintained-engine patch 0051 owns the filename string at those two trace callsites. No server/extension workaround or semantic assertion suppression. Patch 0048's matched Qt probe retained an invalid trace at byte 182878; its structured semantic report remains valid. The original corrupt trace is retained byte for byte. The actual preamble callback canary retains Context beyond buildPreamble, overwrites the caller filename with same-length ASCII x, and proves that old production emits x while fixed production preserves the exact original path.
Removal condition: upstream owns the metadata for its complete event lifetime and the delayed-context canary passes on the bundled base.
Evidence / TODO: engine draft PR #2; owned trace patch and proof; the same test object fails against old production and three focused fixed tests pass22ms. Final raw Qt trace passes strict UTF8/JSON and seven actual filename values, with all four semantic requests passing. Private changed-object links do not qualify native clean recipes. TODO: native canaries and upstream minimal report. This row remains open pending those checks.
Sunrisepeak commentedon Oct 8, 2026
UP-27 · clangd23.1: a default OverlayCDB command mangler is called unconditionally during module scanning
OverlayCDB(&Base)constructor defaults itsCommandManglerto null.OverlayCDB::getProjectModulesnevertheless installs a nonempty callback that unconditionally calls that null mangler. A real required-module scan through this default overlay segfaults at address0; ordinarygetCompileCommandalready guards the same optional mangler.llvmorg-23.1.0source archive; Linux x64 actual private integration control with real CDB and external module provider. This is an API default/null boundary, not a crash claim about the normal ClangdMain path, which supplies a mangler./tmp/mcppls-provider57-build/external-gdb.log; pinned original source extracted readonly as/tmp/mcppls-pinned-GlobalCompilationDatabase.cpp. A production-style explicit noop callback passes but cannot replace the default/null regression.Sunrisepeak commentedon Oct 8, 2026
UP-28 · Header-import preambles lose module visibility; avoiding every module preamble reparses heavy textual headers
Sunrisepeak commentedon Oct 8, 2026
UP-29 · GNU standard-module producer flags enable Clang implicit builtin maps during scanning
Sunrisepeak commentedon Oct 11, 2026
UP-30 · One prerequisite module that does not compile leaves its importers with no module at all
hello.test), the importer gets no module, not evenstd, and completion answers nothing while the status looks ready.WA-CLANGD-014(0.0.8 M-1/M-2): the importers are answered by mcppls's own engine until the module changes. mcppls-clangd 0.0.13 patch 0028 builds and uses the modules that compile, reports the failed one with the compile's first error, and retries the set once the failed source changes; it declarespartial-prerequisite-modules, which retires the workaround.module-faults,failure-at-base; mcppls-clangdPrerequisiteModulesTests.OneFailedModuleLeavesTheOthers,ci/module_resilience_canary.py,tests/e2e/module_dag.py(failure shape).Sunrisepeak commentedon Oct 11, 2026
UP-31 · Completion in a module importer waits without bound for its first preamble and for newly imported modules
--completion-first-preamble-wait-ms, TUSchedulerStaleWithin) and a new import at most 250 ms (--completion-module-wait-ms); past them the answer is the fallback's or the attached modules', marked incomplete, so the client asks again. Declared asbounded-module-wait.TUSchedulerTests.StaleWithinGivesUpOnASlowFirstPreamble,tests/e2e/module_cold_completion.py.Sunrisepeak commentedon Oct 11, 2026
UP-32 · Why a module is rebuilt, and what a file's prerequisites cost, is not logged at the default level
module-rebuild-reasons; mcppls 0.0.13 counts the reasons in its startup line and report.ci/module_resilience_canary.py.