0.0.12 follow-ups: completion waits for missing modules, build.mcpp autosave drops the targets' flags, Windows warm starts rebuild modules, the mcpp version is lost
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 20/100
調査の方向性
Start with the issue’s eight findings and their proposals, then inspect the named entry point src/project/mcpp.cpp and the engine area identified as 0025. Reproduce the completion wait with a cold module cache first; the issue describes a fixture that opens an importer and requests completion every second. Done means missing prerequisites build in the background while completion answers within budget and becomes complete as modules finish; the issue also lists separate proposed fixes and tests for the other findings.
索引モデルが issue の本文から書いたものです。
説明
Summary
The problems found in mcppls 0.0.12 after its release candidate passed CI. Sources: a user's diagnostic bundle (a Qt project with build.mcpp), and a real-project probe on GalTranslPP (Windows, MSVC STL, about 40 C++ modules mixed with <Shlwapi.h>, toml.hpp, proxy and nlohmann json; GalTranslPP#1, run 38148595488, digested by GalTranslPP#5) that compared 0.0.12 with 0.0.11 (stock clangd 23.1). Also the CI fixtures.
What 0.0.12 does better, for context: no clangd exit and no restart while typing on GalTranslPP (0.0.11: 4 exits on a cold start, 4 and 2 restarts while typing, 75 s degraded, a file set aside). Both versions report no false errors in the 7 heavy files. Every kill scenario recovers. The problems below are in order of how much a user feels them.
| # | problem | where | priority |
|---|---|---|---|
| 1 | completion waits for every missing prerequisite module | engine (0025) | high |
| 2 | a half-typed build.mcpp takes the targets' Qt flags away and restarts clangd |
product | high |
| 3 | a warm start on Windows rebuilds most modules | product / engine, cause to confirm | high |
| 4 | the mcpp version is lost after the first describe | product | medium |
| 5 | "ready" while clangd still builds modules for the open files | product | medium |
| 6 | about 0.5 s per completion on Windows in files that mix heavy headers with imports | engine / clang | medium |
| 7 | preambles of heavy-header files are 3× larger on Windows | engine | low |
| 8 | one unexplained 15-minute event-loop stall after a clangd kill (local, not reproduced) | product | low |
1. Completion waits for every missing prerequisite module (high)
Since 0025, completion builds a module newly needed by the file synchronously; only a dependency edit is bounded (250 ms). While a project is being prepared, this means completion waits for every missing prerequisite module.
GalTranslPP, warm typing session (200 s at 10 Hz, cache copied to a new directory, so about 25 modules are rebuilt):
| 0.0.12 | 0.0.11 | |
|---|---|---|
| prerequisite set of Run.cpp ready after | 184–208 s | 75 s |
| clangd completion answers under 1 s | none (median 109 s) | from 5–12 s in, about 0.5 s |
| completions with the expected names | 6 of 21 | 6 of 21 (plain), 8 of 28 |
0.0.11 answers from the preamble while modules are missing. 0.0.12 is more correct once modules exist, but answers nothing in the meantime. On a cold start both versions are unusable for minutes: clangd's completion median is 8 s and its p95 190–240 s, and hover answers only at its 2 s budget.
Proposal: bound the wait for missing prerequisites the way dependency edits are bounded. Answer from the preamble and the modules that exist, keep building in the background, and let mcppls say "modules still being prepared" in the answer.
Test: a fixture that opens an importer on a cold module cache and asks completion every second. Clangd answers within the budget from the first seconds, and the results become complete once the modules are built.
2. A half-typed build.mcpp removes the targets' Qt flags and restarts clangd (high)
From the bundle (VS Code with autosave after 1 s, build.mcpp with mcpp.rules.qt):
- 14:56:54. Autosave →
mcpp emit build-database→ mcpp compilesbuild.mcpp, which fails (build.mcpp:7:5: error: 'mcpp::mcpp' has not been declared). mcpp reportsMCPP_BUILD_DATABASE_PROGRAM_FAILEDand gives a partial description. - The partial description lacks everything
build.mcppcontributes: the Qt include directories, and the generatedmoc_counter.cppandqrc_demo.cpp(engine database changed: 0 added, 2 removed moc_counter.cpp, qrc_demo.cpp, 3 compiled otherwise). - mcppls adopts it. The units' arguments changed, so clangd restarts for the whole project (14:56:56).
src/main.cppthen fails withfatal error: 'QtCore/QObject' file not found, and the status turnsdegraded. - 14:57:51.
build.mcppcompiles again → the full model comes back → another restart (14:57:53). - 14:57:58. The next half-typed save (
'vec' is not a member of 'std') → partial again → a third restart (14:58:13).
That is three clangd restarts in two minutes, with the target code losing its Qt headers the whole time build.mcpp is being typed.
Proposal: on MCPP_BUILD_DATABASE_PROGRAM_FAILED, keep the last complete model for the targets (no plan change, no restart). Show mcpp's compile error as a diagnostic on build.mcpp, and adopt the new description once it compiles.
Test: a fixture that autosaves a broken build.mcpp while a target file is open. No engine-restart; the target keeps its diagnostics and completion; build.mcpp shows the error.
(Open question for mcpp: could emit build-database keep the last successful build-program outputs for the targets when build.mcpp fails?)
3. A warm start on Windows rebuilds most modules (high, cause to confirm)
GalTranslPP, a restart on the same cache: the start begins at 6 of 25 modules prepared, and takes 188 s (0.0.12) or 177 s (0.0.11) to reach ready. Every start reports model-stale and producer-slow (mcpp's emit build-database takes 45–110 s on this project). For 0.0.12 the restart also ended degraded, with producer-partial, which 0.0.11 did not report. On Linux, a warm start rebuilds nothing (ux-mcpp U2: 0 modules rebuilt).
To find out:
- why the cached model is stale at every start;
- whether the new description changes the units' commands, which would key the BMIs differently;
- whether Windows' legacy module cache (no owned cache there) loses BMIs across a clangd restart;
- what the
producer-partialof 0.0.12 says.
Test: a Windows fixture with modules that starts twice on one cache and requires 0 rebuilt modules on the second start, as ux-mcpp U2 does on Linux.
4. The mcpp version is lost after the first describe (medium)
src/project/mcpp.cpp, ProducerAnswers, caches only the "yes, this mcpp produces build databases" answer from mcpp --protocol-version. The version is not cached with it, so every later emit_build_database returns version = "":
report.json→project.producerVersion: ""(the bundle shows one--protocol-versionrun and sixemitruns);- the
build-program-contextdiagnostic for a.mcppfile no set describes says "this mcpp describes the targets only" without naming the version; inputs_fingerprintincludes the producer version, so the cached model's fingerprint changes between the first describe and later ones. This may also play a part in problem 3.
In that bundle the database had 3 sets and no qt-demo:build / mcpp:core, even when emit succeeded. mcpp 2026.10.8.1 through 2026.10.10.2 compile build.mcpp during emit (hence MCPP_BUILD_DATABASE_PROGRAM_FAILED) but do not describe build programs; only 2026.10.11.1 does (#51). The user's mcpp was too old for build.mcpp code intelligence, and mcppls could not tell them.
Proposal: cache the version with the answer (key → version) and fill it in on every describe. Test: two describes through a remembered answer both report the version.
5. "ready" while clangd still builds modules for the open files (medium)
GalTranslPP, cold start (0.0.12): the status was ready, with every open file diagnosed and quiet for 60 s, at 486 s. clangd built its last module at 522 s, and completion in the open files still took several seconds after "ready" (the probe's idle rounds were all at the 1 s budget, empty). A person who sees "ready" and types gets nothing.
Proposal: an open file whose prerequisite set clangd is still building is not ready. Report it, for example "preparing (modules for the open files)", until its set is built.
6. About 0.5 s per completion on Windows in files that mix heavy headers with imports (medium)
ux-modules-windows (<windows.h> in the global module fragments of two module units, and in a file that imports both): idle completion has a p95 of 0.46–0.71 s, and completion while typing has a p95 of 0.79–1.00 s. About a fifth of the completions land past the 1 s budget, depending on the runner. The fixture's budgets were set to p95 1.1 s and engine share 0.65 for 0.0.12. In the same fixture on Linux with Qt, completion takes 0.05 s.
From the debug logs: about 350 ms pass between the module validation and Sema's results. That is the parse of the body against a 28 MB preamble plus the module files whose GMFs hold <windows.h> again. --pch-storage=memory made no difference. Stock clangd has no preamble at all for such a file (seconds per request), so 0.0.12 is still far ahead. But the goal is the Linux number.
To find out: where clang spends those 350 ms on Windows (deserialization of the duplicated declarations of <windows.h> from the PCH and from each module, the merging of their redeclarations); compare with Qt on Linux; look for what can be skipped for a completion.
7. Preambles of heavy-header files are 3× larger on Windows (low)
GalTranslPP: 0.0.12 builds 53 MB preambles in about 7 s for these files. 0.0.11 built 17 MB in 1.4 s, or none at all. This is the intended textual preamble (the headers kept, the imports replayed), but it costs memory or disk per open file and time per rebuild.
To find out: what the extra 36 MB is, and whether the module files' copies of the same headers can be left out of it.
8. One unexplained event-loop stall after a clangd kill (low)
Once, locally, during ux-mcpp's U9 (kill clangd): the server logged the event loop took ... 911383 ms for its timers and never became ready again. Three later runs and CI all passed; the host was heavily loaded (load average 86, swap full). Kept in case it shows up again: if it does, take a stack of the server's threads during the stall.
Next evidence: a steady-state run of the GalTranslPP probe (run 38157130577, E-steady: measure only after clangd has built nothing for four minutes) will say how fast 0.0.12 is on a prepared big Windows project. It will be added here.
- 主要言語
- C++
- スター
- 25
- フォーク
- 2
- 平均マージ
- 21時間 5分
- マージ済み PR(30日)
- 13
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Sunrisepeak/mcpp-language-server のほかの issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
Sunrisepeak/mcpp-language-server#80 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
Sunrisepeak/mcpp-language-server#66 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 1/100
Sunrisepeak/mcpp-language-server#77 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
Sunrisepeak/mcpp-language-server#71 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 15/100
Sunrisepeak/mcpp-language-server#59 ·
メンテナーはふだん 1 日以内に返信
Sunrisepeak/mcpp-language-server の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
xiaoyifang/goldendict-ng#3148 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 91/100
triton-inference-server/server#9069 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 4 日以内に返信
-
documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100