NVML device handle cached at discovery → native access violation (0xc0000005) when the GPU is restarted
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- csharp
- Domain
- operating-systems
Research direction
Read Hardware/Gpu/NvidiaGpu.cs to trace how the NVML handle is acquired and used during Update(), then compare the handle re-acquisition pattern in Hardware/Battery/Battery.cs and commit 9e54127. Reproduce the restart-device scenario with pnputil and verify that polling skips unavailable NVML sensors and resumes without a native access violation.
Written by the indexing model from the issue text.
Description
Stale NVML device handle causes access violation when NVIDIA GPU is restarted or removed
Description
NvidiaGpu acquires its NVML device handle once during construction and stores it in _nvmlDevice. Update() subsequently passes this cached handle to NvidiaML.NvmlDeviceGetPowerUsage.
If the NVIDIA GPU is restarted or removed while LibreHardwareMonitor is polling it (for example, via pnputil /restart-device or during hybrid/eject transitions), the cached handle can become stale. The subsequent native call may then fault inside nvml.dll.
This results in an uncatchable access violation that terminates the host process. The try/catch inside NvidiaML.NvmlDeviceGetPowerUsage cannot intercept the native fault.
Environment
- Windows 11
- .NET 9
- LibreHardwareMonitorLib (
net9.0) - NVIDIA dGPU
Steps to Reproduce
-
Start LibreHardwareMonitor, or another host that polls LibreHardwareMonitor at approximately 1-second intervals.
-
Restart the NVIDIA GPU using:
pnputil /restart-device "<gpuInstanceId>" -
Observe the process during the device removal/reinitialization window.
Expected Behavior
Sensor updates are skipped while the NVIDIA device is temporarily unavailable, and polling resumes once the device becomes available again.
Actual Behavior
The host process terminates due to an access violation in the NVML native call.
Evidence
Application Error:
Faulting module: coreclr.dll
Exception code: 0xc0000005
.NET Runtime:
The process was terminated due to an unhandled exception.
Relevant stack:
at LibreHardwareMonitor.Interop.NvidiaML.NvmlDeviceGetPowerUsage(NvmlDevice)
at LibreHardwareMonitor.Hardware.Gpu.NvidiaGpu.Update()
Root Cause
In Hardware/Gpu/NvidiaGpu.cs, _nvmlDevice is assigned once in the constructor using an NVML device lookup such as:
NvmlDeviceGetHandleByPciBusIdNvmlDeviceGetHandleByIndex
The cached handle is then used by Update() without revalidation.
When the GPU is restarted or temporarily removed, the previously acquired NVML handle may no longer be valid. Although NVML can return a failure NvmlReturn when a device is currently absent, passing a stale handle can instead cause the native code to fault before a return value is produced.
Therefore, the exception cannot reliably be handled by the managed try/catch surrounding the NVML call.
Suggested Fix
Re-acquire the NVML device handle immediately before using it rather than relying on the handle acquired during construction.
The device's PCI bus ID can be captured during construction and used to re-acquire the handle before each update, with adapter index as a fallback if necessary.
If re-acquisition fails or returns null, skip the NVML-dependent sensors for that update instead of calling NVML with the stale handle.
A short-term mitigation could also invalidate _nvmlDevice during Close().
This would make a temporarily missing GPU result in a clean no-op rather than a stale-handle native access violation.
The approach mirrors the existing handle re-acquisition pattern in:
Hardware/Battery/Battery.cs
See commit 9e54127.
- Dominant language
- C#
- Stars
- 9.1k
- Forks
- 1k
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 15
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from LibreHardwareMonitor/LibreHardwareMonitor
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
LibreHardwareMonitor/LibreHardwareMonitor#2407 · 3 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
Difficulty 3/5 1-2 days Newbie friendliness 55/100
All issues in LibreHardwareMonitor/LibreHardwareMonitor
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100