fix: transient WMI fault no longer poisons the static-hardware cache for the session#1416
Merged
Conversation
…for the session
SystemInfoService caches static hardware with ??=, but every Query* helper
returned a NON-NULL fallback on a WMI fault (CpuInfo("Unknown",…),
OsInfo("Windows",…), empty disk/module lists). ??= stored the non-null fallback
and never re-queried, so a transient fault on the first CaptureAsync (plausible
under the ~36-service startup thundering herd -> RPC-server-too-busy) cached the
fallback defaults process-wide (singleton) even after WMI recovered ms later —
Dashboard / System Info / System Report / tray tooltip stuck on 'Unknown CPU' /
'Windows' / no disks / no RAM until restart.
Each Query* now returns null on a WMI FAULT (distinguished from a genuinely
empty-but-successful result, which is still cached), so ??= caches only a
successful query and retries next poll; Capture uses a transient, non-cached
default for the current snapshot only.
Fixes ultra-audit finding P2 #40.
Regression test (integration): CaptureAsync_ReQueriesStaticInfo_AfterCacheCleared
— after a successful capture, nulling _cachedCpuStatic (the post-fault state the
fix now produces) and re-capturing must repopulate a real CPU, proving a
cleared/null cache is retried rather than left permanently degraded.
…hangelog conflicts)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes ultra-audit finding P2 #40.
SystemInfoServicecaches static hardware info with??=, but everyQuery*helper returned a non-null fallback on a WMI fault (CpuInfo("Unknown", …),OsInfo("Windows", …), an empty disk/module list). Because the fallback was non-null,??=stored it and never re-queried. So if the firstCaptureAsyncraced a transient WMI fault — plausible under the app's documented ~36-service startup thundering herd →RPC server too busy(0x800706BB) — the fallback defaults were cached process-wide (the service is a singleton) even after WMI recovered milliseconds later. The Dashboard, System Info tab, System Report and tray tooltip then permanently showed "Unknown CPU" / "Windows" / no disks / no RAM modules until the app was restarted.Fix
Cache only a successful query:
QueryOsStatic/QueryCpuStaticreturnnullon a WMI fault (a successful no-rows result still returns the "unknown" answer and is cached).QueryDisks/QueryMemoryModulesreturnnullonly when a fault yielded nothing; a genuinely empty-but-successful enumeration (or a partial list gathered before a fault) is a usable answer and is cached.Captureuses a transient, non-cached default for the current snapshot when the cache is still null, so??=retries on the next poll.Regression test (integration)
CaptureAsync_ReQueriesStaticInfo_AfterCacheCleared: after a successful capture populates the cache, nulling_cachedCpuStatic(the post-fault state the fix now produces) and re-capturing must repopulate a real CPU — proving a cleared/null cache is retried, not left permanently degraded. Red before the fix (the fault path cached a non-null fallback, so the cache was never null to retry).Checks