reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,179 @@
---
name: windbg-diagnostic-method
description: Use with every WinDbg plugin investigation to apply evidence-first reasoning, confidence calibration, contrarian review, structured reporting, and deterministic validation. Not a bug-family-specific triage skill.
user-invocable: false
---
# WinDbg Diagnostic Method
Apply this method alongside the bug-family-specific skill selected for an
investigation. Pattern matches route the investigation; they do not prove the
root cause.
## Evidence ladder
Prefer direct evidence in this order:
1. Faulting instruction/context, bugcheck or exception parameters, and resource
owners/waiters from the actual dump or trace.
2. Matching symbols and the user's authorized source for the involved build.
3. Allocation/free, Verifier, IRP, lock, ETW, WCT, or TTD history captured for
the same failure.
4. Controlled reproduction and instrumentation.
5. Pattern guidance as a hypothesis only.
Never claim commands, source access, or artifacts that are unavailable in the
session.
## First-pass normalization
- Confirm process dump versus kernel dump and target architecture/build.
- Load public Windows symbols and matching symbols for user/vendor modules.
- Record missing pages, symbols, related-process dumps, trace scope, and tool
availability.
- User-mode exception: `.exr -1`, `.ecxr`, stack, and registers.
- Kernel bugcheck: `.bugcheck`, `!analyze -v`, then documented context/trap
recovery for that code.
- Hang: identify the affected operation, wait type, owner/server, and deepest
supported blocker.
- Memory: distinguish corruption, address-space pressure, and commit/limit
failures before choosing a fix.
## Five-phase investigation
1. **OBSERVE**: establish dump/trace type, architecture, symbols, code, stack,
registers, thread/resource state, and missing evidence.
2. **HYPOTHESIZE**: form a specific primary mechanism and at least two plausible
alternatives when the evidence permits.
3. **TEST**: identify direct debugger, source, trace, or reproduction evidence
that distinguishes the hypotheses. Absence of evidence is not evidence of
absence.
4. **EVALUATE**: record supporting, contradictory, and missing evidence.
5. **CONCLUDE or PIVOT**: name the violated invariant and verification plan, or
remain `candidate-pending-verification`.
## Routing index
| Evidence | Skill |
|---|---|
| Native user-mode exception in an app, service, or UMDF/user-mode driver host | `windbg-user-exception-triage` |
| User-mode heap corruption or allocation/free history | `windbg-user-heap-corruption-investigation` |
| Cross-thread/process, COM/RPC, or service wait | `windbg-user-wait-chain-analysis` |
| User-mode TTD history question | `windbg-user-ttd-reverse-debugging-triage` |
| User-mode VA fragmentation, allocation failure, or commit pressure | `windbg-user-virtual-memory-exhaustion` |
| Thread-affine lock across coroutine suspension | `windbg-user-mutex-held-across-co-await` |
| Kernel bugcheck, trap frame, or saved context | `windbg-kernel-bugcheck-triage` |
| Driver Verifier violation | `windbg-kernel-verifier-triage` |
| Outstanding/power IRP, completion, or cancellation | `windbg-kernel-irp-lifecycle-triage` |
| Kernel lock owner/waiter chain | `windbg-kernel-lock-deadlock-triage` |
These are the complete bug-family routes. Continue evidence-led reasoning for
unsupported families; never dispatch to an absent skill.
## Routing depth
- **Fast (indicative diagnosis confidence >=0.80)**: validate the apparent
pattern, its required evidence, and plausible alternatives.
- **Validate (0.40-0.79)**: test the leading pattern and at least one plausible
alternative through the full cycle.
- **Full reasoning (<0.40 or no match)**: reason from observations and preserve
explicit uncertainty.
Confidence is explanatory judgment, not measured probability.
## Trigger and fix gates
- Verify the trigger in the dump, disassembly, source, trace, or controlled
reproduction before declaring a final fix.
- Name the violated invariant and the parties or path that violate it.
- Separate the detector or victim from the original writer, freeing actor, or
resource holder.
- A fix must restore the violated invariant, not merely suppress the reproducer.
- If the trigger is unverified, use `candidate-pending-verification`, set the
fix to null or a verification plan, and name the evidence/fix matrix needed.
- Do not blame a module solely from a bucket or `MODULE_NAME`.
## Fix-confidence calibration
Diagnosis confidence and fix confidence are separate. Every proposed fix must
declare `fix_confidence` and one `fix_code_path_coverage` value:
| Fix confidence | Required coverage |
|---|---|
| `>=0.90` | `read-this-session`: the actual fix path was read in this investigation. |
| `0.70-0.89` | `read-prior-session` or `symbol-or-disassembly`: direct coverage exists, but the complete source path was not read in this investigation. |
| `0.50-0.69` | `pattern-only`, or incomplete symbol/disassembly evidence. Treat the fix as a candidate. |
| `<0.50` | `not-read`: no direct fix-path coverage. Keep the diagnosis candidate-pending-verification and set the fix to null or a verification plan. |
Lower confidence is always allowed when evidence quality, path coverage, or
alternatives warrant it. Never raise confidence to fit the table.
## Independent review
Before finalizing a full diagnosis:
1. When the host supports the bundled Copilot agents, invoke the `contrarian`
agent once with the complete proposed diagnosis.
2. When the host cannot run that agent, state that the independent review did
not run; do not silently substitute inline self-review.
3. If the verdict is `CHALLENGED`, test the counter-hypothesis with direct
evidence, then downgrade confidence or remain pending verification.
4. Stop after one loopback. A second challenge remains pending verification.
Record `contrarian_loopback` as the Boolean `true` or `false`.
## Report contract
A full report contains these H2 sections in order:
1. Analysis
2. Root Cause
3. Fix
4. Reasoning Chain
5. Alternatives Considered
6. Trigger Verification
7. Mermaid
8. Contrarian Verdict
9. JSON Output Contract Summary
The Trigger Verification section must distinguish observed, contradictory, and
missing evidence plus fix validation. Mermaid must reflect verified evidence.
The JSON summary must include:
- `diagnosis_status`
- `routing_path`
- `root_cause`
- `confidence`
- `fix_confidence`
- `fix_code_path_coverage`
- `contrarian_review`
- `contrarian_loopback`
## Deterministic report validation
After writing the report, run the bundled validator with PowerShell 7:
```powershell
pwsh -NoProfile -File <skill-directory>\scripts\validate-diagnosis-output.ps1 `
-Path <diagnosis-markdown-path>
```
Use the installed `windbg-diagnostic-method` directory for
`<skill-directory>`. The script checks each section body independently,
requires at least two alternatives, accepts explicit or implicit Mermaid
participants, parses the JSON summary, and exits nonzero on failure.
Correct failed checks and rerun the script before presenting the report as
structurally complete. Structural validation does not replace technical review.
## Safety and privacy
Dumps, traces, ETLs, CABs, source, paths, tokens, and memory contents can be
sensitive. Obtain authorization before capture, configuration changes, or
sharing. Verifier and Page Heap can disrupt workloads and require a recoverable
test plan plus restoration steps. Public feedback follows `FEEDBACK.md` and
defaults to a minimal reviewed summary with no automatic attachments.
## Feedback
For feedback about this method or validator, follow the package `FEEDBACK.md`.
Do not attach private diagnosis files automatically.

View File

@@ -0,0 +1,169 @@
param(
[Parameter(Mandatory = $true)]
[string]$Path
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
throw "Diagnosis file not found: $Path"
}
$resolvedPath = (Resolve-Path -LiteralPath $Path).Path
$content = Get-Content -LiteralPath $resolvedPath -Raw
function Get-SectionMatch {
param([Parameter(Mandatory = $true)][string]$HeadingPattern)
$pattern = "(?ims)^##\s+(?:$HeadingPattern)\b[^\r\n]*\r?\n(?<body>.*?)(?=^##\s+|\z)"
return [regex]::Match($content, $pattern)
}
function Test-MermaidDiagram {
$blocks = [regex]::Matches($content, '(?ims)^```mermaid\s*\r?\n(?<body>.*?)^```\s*$')
foreach ($block in $blocks) {
$body = $block.Groups["body"].Value
if ($body -match '(?im)^\s*sequenceDiagram\s*$') {
$actors = [System.Collections.Generic.HashSet[string]]::new(
[System.StringComparer]::OrdinalIgnoreCase
)
foreach ($match in [regex]::Matches(
$body,
'(?im)^\s*(?:participant|actor)\s+([A-Za-z0-9_.-]+)'
)) {
[void]$actors.Add($match.Groups[1].Value)
}
foreach ($match in [regex]::Matches(
$body,
'(?im)^\s*([A-Za-z0-9_.-]+)\s*(?:--?>>|->>|--?>|--x|-x|--\)|-\))\s*([A-Za-z0-9_.-]+)\s*:'
)) {
[void]$actors.Add($match.Groups[1].Value)
[void]$actors.Add($match.Groups[2].Value)
}
if ($actors.Count -ge 2) {
return $true
}
}
if ($body -match '(?im)^\s*(?:flowchart|graph)\b') {
$nodes = [System.Collections.Generic.HashSet[string]]::new(
[System.StringComparer]::OrdinalIgnoreCase
)
foreach ($match in [regex]::Matches(
$body,
'(?im)^\s*([A-Za-z0-9_]+).*?(?:-->|---|-.->|==>)\s*([A-Za-z0-9_]+)'
)) {
[void]$nodes.Add($match.Groups[1].Value)
[void]$nodes.Add($match.Groups[2].Value)
}
if ($nodes.Count -ge 2) {
return $true
}
}
}
return $false
}
$analysis = Get-SectionMatch "Analysis"
$rootCause = Get-SectionMatch "Root Cause"
$fix = Get-SectionMatch "Fix"
$reasoning = Get-SectionMatch "Reasoning Chain"
$alternatives = Get-SectionMatch "Alternatives(?: Considered)?"
$trigger = Get-SectionMatch "Trigger Verification"
$contrarian = Get-SectionMatch "Contrarian Verdict"
$alternativeCount = 0
if ($alternatives.Success) {
$alternativeCount = [regex]::Matches(
$alternatives.Groups["body"].Value,
'(?m)^\s*(?:[-*+]\s+|\d+[.)]\s+)'
).Count
}
$triggerBody = if ($trigger.Success) { $trigger.Groups["body"].Value } else { "" }
$triggerTableRows = [regex]::Matches($triggerBody, '(?m)^\s*\|.*\|\s*$').Count
$contrarianBody = if ($contrarian.Success) {
$contrarian.Groups["body"].Value
} else {
""
}
$results = [ordered]@{
AnalysisHeading = $analysis.Success
RootCauseHeading = $rootCause.Success
FixHeading = $fix.Success
ReasoningChain = (
$reasoning.Success -and
$reasoning.Groups["body"].Value -match 'OBSERVE|HYPOTHESIZE|TEST|EVALUATE|CONCLUDE'
)
Alternatives = ($alternatives.Success -and $alternativeCount -ge 2)
TriggerVerification = (
$trigger.Success -and
$triggerTableRows -ge 3 -and
$triggerBody -match '(?i)\bVERIFIED\b|\bUNVERIFIED\b|verified by'
)
MermaidDiagram = Test-MermaidDiagram
ContrarianVerdict = (
$contrarian.Success -and
$contrarianBody -match '\bACCEPTED\b|\bCHALLENGED\b' -and
$contrarianBody -match '(?i)contrarian_loopback[^:\r\n]*:\s*(?:true|false)\b'
)
JsonSummary = $false
}
$requiredJsonProperties = @(
"diagnosis_status",
"routing_path",
"root_cause",
"confidence",
"fix_confidence",
"fix_code_path_coverage",
"contrarian_review",
"contrarian_loopback"
)
foreach ($block in [regex]::Matches($content, '(?is)```json\s*(?<body>.*?)```')) {
try {
$json = $block.Groups["body"].Value | ConvertFrom-Json
} catch {
continue
}
$propertyNames = @($json.PSObject.Properties.Name)
$hasRequiredProperties = $true
foreach ($property in $requiredJsonProperties) {
if ($propertyNames -notcontains $property) {
$hasRequiredProperties = $false
break
}
}
if (
$hasRequiredProperties -and
$json.contrarian_loopback -is [bool]
) {
$results.JsonSummary = $true
break
}
}
$pass = @($results.Values | Where-Object { $_ -eq $false }).Count -eq 0
$output = [pscustomobject]@{
Pass = $pass
File = $resolvedPath
Checks = [pscustomobject]$results
}
$output | ConvertTo-Json -Depth 5
if (-not $pass) {
exit 1
}

View File

@@ -0,0 +1,129 @@
---
name: windbg-kernel-bugcheck-triage
description: 'Use when a kernel dump reports a Windows bugcheck; decode parameters and recover exception or trap context before investigating your driver. Not for user-mode process crashes or blaming a module from its name alone.'
---
# Kernel Bugcheck Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Scope
Use a kernel crash dump or authorized live kernel session. A process dump
captured after a reboot does not contain the earlier kernel fault. Confirm
the dump type with the debugger, not a filename or the user's visible symptom.
This skill includes exception-context and trap-frame recovery.
## Workflow
### 1. Establish symbols and bugcheck evidence
```text
.symfix
.sympath+ <your-vendor-symbol-directory>
.reload
!analyze -v
.bugcheck
k
```
Replace the placeholder with the approved symbol location for your own binaries.
Record dump type, target architecture/build, bugcheck code and parameters,
faulting instruction, and available memory. Public Windows symbols suffice
for many investigations; do not require private Windows source or PDBs.
### 2. Decode parameters for the specific code
| Code | Parameter meaning / next step |
|---|---|
| `0x1E` | P1 exception code; P2 exception address; P3/P4 exception-specific information. These are not generically a CONTEXT pair. |
| `0x7E` | P1 exception code; P2 exception address; P3 EXCEPTION_RECORD; P4 CONTEXT. |
| `0x3B` | P1 exception code; P2 instruction address; P3 CONTEXT; P4 unused. |
| `0x0A` / `0xD1` | Referenced address, IRQL, access information, instruction address. Decode the access field for that code; these parameters are not generally a trap-frame pointer. |
| `0x50` | Invalid memory reference; parameter interpretation varies with target version. Consult the code reference. |
| `0x9F` | P1 selects the power-failure subtype; use its specific parameter table and `windbg-kernel-irp-lifecycle-triage` where applicable. |
| Verifier-class stop | Use `windbg-kernel-verifier-triage` and the exact code/subcode definition. |
Do not reuse a parameter layout across different bugchecks.
### 3. Recover the original faulting context
For `0x7E`:
```text
.exr <P3>
.cxr <P4>
kb
r
```
For `0x3B`:
```text
.cxr <P3>
kb
r
```
For other exception-style bugchecks, locate a valid saved exception/context
using the documented code procedure and available analysis output. Do not
guess `.cxr` arguments from arbitrary P1..P4 values.
When `!analyze -v` or verified stack evidence identifies a `TRAP_FRAME`:
```text
.trap <trap-frame-address>
kb
r
```
Trap frames can be partial: some registers may be missing or reconstructed
incorrectly. Note the debugger's warnings and do not treat unsaved registers as
reliable evidence. If a frame is missing, malformed, or absent from the dump,
report the limitation rather than scanning arbitrary pointers and claiming a
recovered context.
### 4. Investigate the driver, not just the detector
```text
!thread
lmvm <driver-module>
.frame /r <frame-number>
```
Inspect the recovered instruction, register/object used, IRQL, ownership,
and nearby driver frames. A crash in an operating-system routine may result
from prior driver corruption. Conversely, a third-party name in
`MODULE_NAME` does not establish that the named driver caused the failure.
Verify vendor build identity against the matching binary/PDB.
For concurrency or blocked requests use `windbg-kernel-lock-deadlock-triage` or
`windbg-kernel-irp-lifecycle-triage`. Kernel `~` commands select processors, not the
application thread list; use documented thread/process inspection such as
`!thread` and `!process 0 7`.
## Validation
Record the decoded parameters, recovered context and its limitations, and the
evidence connecting the driver's operation to the violated invariant. Test
competing lifetime, bounds, IRQL, and synchronization explanations. Recommend
an instrumented test/repro only with approval; route Verifier evidence to
`windbg-kernel-verifier-triage`. Do not call a guessed module assignment a proven cause.
## References
- [Bugcheck reference](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-code-reference2)
- [0x3B SYSTEM_SERVICE_EXCEPTION](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0x3b--system-service-exception)
- [0x7E SYSTEM_THREAD_EXCEPTION_NOT_HANDLED](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0x7e--system-thread-exception-not-handled)
- [Context record](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-cxr--display-context-record-)
- [Trap frame](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-trap--display-trap-frame-)
## Feedback
Follow `FEEDBACK.md` and submit only reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-bugcheck-triage` and the package version from `plugin.json`; no
automatic kernel dump, private-symbol, or source upload.

View File

@@ -0,0 +1,101 @@
---
name: windbg-kernel-irp-lifecycle-triage
description: 'Use when kernel evidence shows stalled I/O, a power IRP, or completion/cancellation misuse; inspect request state and driver ownership. Not for interpreting an empty IRP search in a limited dump as proof of healthy I/O.'
---
# IRP Lifecycle Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Scope
Investigate I/O Request Packets in a kernel dump or authorized live kernel
session. Examples include `0x9F` power failures and hangs where progress
depends on a driver request. Apply the parameter table for the specific
bugcheck subtype rather than assuming every `0x9F` identifies the same object.
For `0x9F` with P1 equal to `3`, P4 is the blocked IRP. Inspect that directly
before running a system-wide search.
## Workflow
### 1. Decode the known request
```text
!analyze -v
!irp <irp-address>
```
When no request address is known and the dump has the required pool data:
```text
!irpfind
```
`!irpfind` can be expensive in a live session and incomplete in a limited dump.
Use supported filters where appropriate. No result does not prove there are
no outstanding requests.
### 2. Follow the stack and ownership
Record the major/minor operation, current stack location, device/driver stack,
completion routine, pending flags, cancellation state, and any relevant thread.
Use the available device stack and driver source to establish which component
is expected to advance or complete the request.
Do not identify an offending driver solely by the last name printed in the IRP
stack. A completion routine, downstream dependency, or framework-owned request
may change the responsible path.
### 3. Correlate dependencies
| Evidence | Next investigation |
|---|---|
| I/O verifier violation or available shadow history | `windbg-kernel-verifier-triage` |
| Owner/waiter kernel lock chain | `windbg-kernel-lock-deadlock-triage` |
| Exception or trap during request handling | `windbg-kernel-bugcheck-triage` |
Preserve evidence between skills; avoid repeatedly handing the same unchanged
IRP back and forth.
### 4. Test the request protocol
- **Power request:** inspect the subtype's objects and power/PnP state,
current stack location, and completion dependency.
- **Cancellation race:** establish which routine owns completion, how
cancellation synchronizes with normal completion, and whether the request
can be completed twice or retained after cancellation.
- **Double completion:** trace competing terminal paths; a single live IRP
snapshot may not contain enough history.
- **Pending request:** verify API/framework-specific pending and completion
rules, remove/shutdown paths, and who promises eventual progress.
WDM and WDF have different ownership APIs. Do not transplant a raw WDM
completion/cancel pattern into a framework-owned request without checking its
contract. This skill establishes evidence; it is not a complete I/O protocol
reference or a decoder for every power subtype.
## Validation
Name the operation, current owner/dependency, and supported protocol violation
or stalled path. Test normal completion, concurrent cancellation, removal,
power transitions, and shutdown where relevant. If history is missing, propose
an approved instrumented test using the verifier skill rather than inventing
which driver lost the completion.
## References
- [IRP inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-irp)
- [IRP search](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-irpfind)
- [0x9F power-state failure](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0x9f--driver-power-state-failure)
- [Canceling IRPs](https://learn.microsoft.com/windows-hardware/drivers/kernel/canceling-irps)
## Feedback
Follow `FEEDBACK.md` and report only reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-irp-lifecycle-triage` and the package version from `plugin.json`; no
automatic kernel dump or request-content upload.

View File

@@ -0,0 +1,105 @@
---
name: windbg-kernel-lock-deadlock-triage
description: 'Use when kernel threads block on driver synchronization or Verifier reports a lock-order violation; build an owner/waiter graph. Not for treating every watchdog stop as a deadlock or listing every lock type with !locks.'
---
# Kernel Lock and Deadlock Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
Use kernel thread stacks, synchronization-object evidence, and Driver Verifier
deadlock records. A watchdog bugcheck can indicate CPU/DPC progress failures,
not necessarily a lock cycle. Establish the actual waits before choosing this
workflow.
## Workflow
### 1. Gather owners and waiters
```text
!locks
!thread <ethread-address>
!process 0 7
```
`!locks` enumerates ERESOURCE information. It is not an inventory of all
pushlocks, fast mutexes, and spinlocks. For other primitives use documented
primitive-specific inspection when available, matching symbols for your
driver, its source, and recorded acquisition evidence. State missing owners
explicitly.
### 2. Inspect recorded lock-order evidence
If Driver Verifier deadlock detection was enabled and the dump contains its
records:
```text
!deadlock 1
```
Inspect the reported resources, acquisition sequence, and threads. Verifier
can detect an unsafe ordering before a persistent deadlock actually forms.
An empty result without the required verification/history is not proof that
the lock order is safe. For Verifier setup/safety use `windbg-kernel-verifier-triage`.
### 3. Build and test the graph
```text
thread A holds resource X -> waits for Y owned by B
thread B holds resource Y -> waits for X owned by A
```
Show evidence for every edge. Check recursive acquisition, callbacks under
locks, I/O completion dependencies, and destruction/rundown paths.
Distinguish:
- A demonstrated cycle or Verifier-reported order inversion.
- Contention where a runnable owner can progress.
- Starvation or an owner blocked on a separate request.
- Spin/IRQL problems, which are not necessarily blocking-lock deadlocks.
If blocked on an IRP use `windbg-kernel-irp-lifecycle-triage`; if a chain crosses into a
user-mode COM/RPC operation use `windbg-user-wait-chain-analysis`. Carry the proven graph
edges into the next skill rather than starting the same investigation again.
### 4. Localize the driver path
Identify which call path held one resource while acquiring/waiting for another.
Check the required IRQL, permitted waits, lock hierarchy, and object lifetime.
Private Windows implementation layouts are not prerequisites; if public
symbols and captured state cannot recover an edge, request appropriate
authorized evidence and keep the conclusion provisional.
## Fix patterns
Use a consistent acquisition hierarchy, reduce lock scope, avoid unbounded
waits/cross-component callbacks while holding resources, and move potentially
blocking destruction outside locks where the ownership design permits.
Do not replace a lock or add a timeout without preserving invariants and
completion/cancellation semantics.
## Validation
Record the graph, supported cycle/inversion, and offending driver path.
Test concurrency, callbacks, teardown, and the same applicable Verifier checks.
Separate a demonstrated fix from an unproven contention hypothesis.
## References
- [ERESOURCE locks extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-locks)
- [Deadlock extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-deadlock)
- [Driver Verifier deadlock detection](https://learn.microsoft.com/windows-hardware/drivers/devtest/deadlock-detection)
- [Thread inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-thread)
## Feedback
Follow `FEEDBACK.md` and report reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-lock-deadlock-triage` and the package version from `plugin.json`; no
automatic dump, lock-history transcript, or driver-source upload.

View File

@@ -0,0 +1,107 @@
---
name: windbg-kernel-verifier-triage
description: 'Use when a kernel dump contains Driver Verifier violations; inspect flags, bugcheck subcodes, and available I/O shadow state. Not for Application Verifier user-mode stops or inferring a violation from enabled flags alone.'
---
# Driver Verifier Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Scope
Driver Verifier checks kernel driver contracts. Application Verifier is a
different user-mode facility; use `windbg-user-heap-corruption-investigation` for its heap
stops. Enabled Driver Verifier flags alone do not prove a contract violation.
Use this skill when a verifier-class bugcheck or analysis identifies an actual
violation. Examples include `0xC4`, `0xC9`, and `0xE6`; inspect the exact code
and parameters rather than treating every stop as the same family.
## Workflow
### 1. Preserve code, subcode, and active configuration
```text
!analyze -v
.bugcheck
!verifier
k
```
Record the bugcheck, subtype/subcode, offending operation and driver when
reported, enabled checks, target build, and evidence availability. Decode each
subcode against its documented contract. Existing output may be incomplete in
a small dump; do not discard captured evidence merely because live
configuration is now different.
### 2. Decode available I/O history
When the violation supplies an appropriate IRP address and I/O verification
state is available:
```text
!iovirp <irp-address>
!irp <irp-address>
```
Shadow state may preserve information lost from the live request. Correlate it
with the decoded contract and use `windbg-kernel-irp-lifecycle-triage` for completion,
cancellation, pending state, and ownership.
### 3. Recover context or follow dependencies
- Saved exception/trap context: `windbg-kernel-bugcheck-triage`.
- Lock-order evidence: `windbg-kernel-lock-deadlock-triage`.
- Outstanding or power request: `windbg-kernel-irp-lifecycle-triage`.
Avoid cyclic dispatch. Carry the evidence already collected to the next skill;
re-enter only when a distinct evidence requirement exists.
### 4. Investigate uncovered violations
For a generic DDI violation, identify the exact precondition (IRQL, lifetime,
parameters, or ownership) and the driver call that broke it. For a DMA violation,
inspect supported adapter/map/unmap and buffer-lifetime evidence for that
subcode. This package does not provide a specialized decoder for every DDI or
DMA case; state the gap and continue from documentation and driver source.
## Controlled repro
Do not enable Driver Verifier without approval. It can deliberately crash the
system and expose boot-critical defects. Use a recoverable test machine, save
the current configuration, select relevant vendor drivers/checks, and agree on
rollback before restarting. Do not verify every installed driver by default.
Read-only configuration inspection on a test machine:
```text
verifier /querysettings
```
`verifier /reset` clears settings and normally requires a restart to stop
verification; it is a configuration change, not a harmless query. Restore
previous intentional settings rather than unconditionally clearing them.
## Validation
Name the exact violated contract, link the recorded operation to driver source,
and test that the remedy satisfies it under the same checks and workload.
Record dump/verification limitations and unverified assumptions. Passing a
single repro is not proof that every driver path is safe.
## References
- [Driver Verifier](https://learn.microsoft.com/windows-hardware/drivers/devtest/driver-verifier)
- [Verifier extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-verifier)
- [I/O verifier IRP extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-iovirp)
- [0xC4 verifier violation](https://learn.microsoft.com/windows-hardware/drivers/debugger/bug-check-0xc4--driver-verifier-detected-violation)
## Feedback
Follow `FEEDBACK.md` and submit reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-kernel-verifier-triage` and the package version from `plugin.json`; do not
automatically upload dumps or proprietary driver source.

View File

@@ -0,0 +1,98 @@
---
name: windbg-user-exception-triage
description: 'Use when a native C/C++ app, service, or user-mode driver host (including UMDF) crashes with a structured exception in a dump or WinDbg session, including native faults inside managed processes. Not for managed .NET exceptions, WinUI/XAML app errors, or kernel bugchecks.'
---
# User-Mode Exception Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## When to use
Start here for access violations, heap corruption, stack overflow, fail-fast,
breakpoints, and other structured exceptions in a native application, service,
or user-mode driver host process dump. This includes UMDF driver failures that
occur in their user-mode host. Confirm
the dump type from WinDbg; the filename extension alone does not distinguish
user-mode from kernel-mode dumps.
## Workflow
### 1. Establish the exception context
```text
.exr -1
.ecxr
k
!analyze -v
```
Record the exception code, address, parameters, access type, registers, module,
and stack. `.ecxr` selects the saved exception context when available. If no
exception context was captured, report that limitation rather than treating the
currently selected thread as the faulting thread.
Use matching binaries and PDBs for your modules and public Windows symbols.
Investigate mismatches or truncated stacks before naming a failing source line.
### 2. Classify and choose an available investigation
| Evidence | Next step |
|---|---|
| `0xC0000005` with allocation/free or overrun evidence | `windbg-user-heap-corruption-investigation` |
| `0xC0000374` heap corruption | `windbg-user-heap-corruption-investigation` |
| `0xC0000017`, `0x8007000E`, or an allocation-failure path | `windbg-user-virtual-memory-exhaustion` |
| Lock/unlock failure following coroutine suspension | `windbg-user-mutex-held-across-co-await` |
| A TTD recording is available and earlier mutation is in question | `windbg-user-ttd-reverse-debugging-triage` |
| No crash exception and evidence of blocked work | `windbg-user-wait-chain-analysis` |
| A kernel dump reports a bugcheck | `windbg-kernel-bugcheck-triage` |
Do not classify every address in a heap range as a lifetime bug. Check access
type, faulting instruction, object layout, and valid allocation boundaries.
### 3. Investigate families without a dedicated skill
- **Access violation without a match:** identify the read/write/execute target,
object/register used, and whether bounds, ownership, or synchronization was
violated. Distinguish a null pointer from stale or corrupted state.
- **`0xC0000409` / fail-fast:** inspect exception parameters and the documented
fast-fail subcode, then the failing condition and call path. The historical
status name alone does not prove a buffer overrun or rule one out. Not every
fast-fail carries an HRESULT.
- **`0xC00000FD` / stack overflow:** inspect stack bounds and frame sizes; test
recursion, reentrancy, large frames, and inability to commit stack growth.
Use the memory-exhaustion skill when commit evidence supports that branch.
- **`0xE06D7363` / MSVC C++ exception:** establish whether it was handled,
identify the throw/catch path with available symbols, and inspect the
exception information supported by the runtime/version. A first-chance throw
is not automatically a defect. This package does not decode thrown-object
layouts or fully diagnose `noexcept`/termination behavior.
- **Stowed/WinRT exceptions:** preserved error information can precede the
final failure. Correlate its originating stack and nested errors with the
application; this package does not include a XAML extension workflow.
- **Illegal instruction or breakpoint:** distinguish CPU/architecture or
code-corruption hypotheses from intentional assertions/debug breaks.
## Validation
- Exception context and code are established, or their absence is stated.
- Faulting instruction and relevant object/register agree with the hypothesis.
- Alternatives are tested against evidence, not just stack names.
- Missing memory, symbols, and specialized exception coverage are explicit.
- The proposed fix addresses a demonstrated invariant and has a repro/test plan.
## References
- [Exception context](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-ecxr--display-exception-context-record-)
- [Exception record](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-exr--display-exception-record-)
- [Controlling exceptions and events](https://learn.microsoft.com/windows-hardware/drivers/debugger/controlling-exceptions-and-events)
## Feedback
For this skill, follow the plugin's `FEEDBACK.md` and report a reviewed, sanitized
issue to [WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-exception-triage` and the package version from `plugin.json`; do not
upload dumps or private source automatically.

View File

@@ -0,0 +1,124 @@
---
name: windbg-user-heap-corruption-investigation
description: 'Use when an app, service, or user-mode driver host heap fails or Application Verifier detects corruption; inspect history and bounds. Not for kernel pool corruption or ordinary OOM.'
---
# Heap Corruption Investigation
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection and limits
Look for `STATUS_HEAP_CORRUPTION` (`0xC0000374`), Application Verifier stops,
or failures in heap allocate/free/reallocate paths in an application, service,
or user-mode driver host such as an UMDF host process. A crash inside the allocator
may be the first detection of an earlier bad write, not the faulty operation.
Distinguish corruption from allocation failure; for the latter use
`windbg-user-virtual-memory-exhaustion`.
Allocation/free history depends on how the process was instrumented and which
pages were captured. A missing history is a limitation, not proof of a leak or
use-after-free.
## Workflow
### 1. Decode the stop
```text
.exr -1
.ecxr
!analyze -v
k
```
Record the stop reason, corrupted block, corruption address, and the operation
that detected the damage. If a verifier stop frame has parameter/local symbols,
select it with `.frame /r <frame>` and inspect `dv`; otherwise use the captured
stop output and the documented stop definition. Do not assume one fixed
parameter layout or a stop code shared by all verifier versions.
### 2. Recover available block history
```text
!heap -p -a <address>
!avrf -hp -a <address>
```
The first command inspects a Page Heap allocation; the second searches available
Application Verifier heap-operation history. Use `!heap -?` and `!avrf -?` to
confirm support in the installed extension. On an uninstrumented dump these
commands may not recover the history needed to identify the writer.
Capture allocation and free stacks when present. Check the address is inside
the user allocation rather than a header or neighboring block.
### 3. Test competing explanations
| Hypothesis | Evidence to seek |
|---|---|
| Use-after-free | Confirmed free before a later access through a retained reference |
| Double-free | Two ownership/completion paths freeing the same allocation |
| Overrun/underrun | A write outside the allocated user bounds |
| Wild write | Corrupted header or payload and a writer with an invalid target |
| Allocation/free contract mismatch | Different allocator/deallocator or incorrect owning heap |
Inspect bytes with `db <address> L<size>` and disassembly around the access.
Fill patterns and plausible pointers are clues, not causal proof. Correlate with
source, history, or a repro and trace the ownership transition.
### 4. Obtain stronger evidence if necessary
With user approval, enable full Page Heap for a named test executable:
```text
gflags /p /enable target.exe /full
```
Restart that process and reproduce under the debugger. Application Verifier
heap checks can also be configured for that test executable. Explain memory
overhead, timing changes, and potential deliberate stops before doing this.
Record the previous settings and restore them when finished; if Page Heap was
newly enabled for this test, disable it with:
```text
gflags /p /disable target.exe
```
Do not change an existing application's verification policy without approval.
If a user-mode TTD trace is available, use `windbg-user-ttd-reverse-debugging-triage` to
find the relevant mutation or free.
## Fix patterns
- Enforce the actual lifetime contract with ownership types or explicit
acquire/release rules. Shared ownership is appropriate only when the design
genuinely has multiple owners.
- Synchronize shared state separately: `shared_ptr` ownership does not make a
concurrently modified cache or pointed-to object thread-safe.
- Size buffers and check arithmetic, lengths, and terminators; use bounds-aware
containers where appropriate.
- Keep allocation and deallocation compatible across DLL/API boundaries.
## Validation
Establish the affected block and supported corruption class, name the path that
violated bounds or ownership, and distinguish the detector from the writer.
Exercise the fix with the same instrumentation and relevant concurrency/load.
Report unresolved writer history rather than presenting a guessed fix as proven.
## References
- [Application Verifier stop definitions](https://learn.microsoft.com/windows-hardware/drivers/devtest/application-verifier-stop-codes-and-definitions)
- [Heap extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-heap)
- [Application Verifier extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-avrf)
- [GFlags and Page Heap](https://learn.microsoft.com/windows-hardware/drivers/debugger/gflags-and-pageheap)
## Feedback
Follow `FEEDBACK.md` and report reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-heap-corruption-investigation` and the package version from
`plugin.json`; no automatic dump, source, or transcript upload.

View File

@@ -0,0 +1,86 @@
---
name: windbg-user-mutex-held-across-co-await
description: 'Use when app, service, or user-mode driver C++ coroutine code holds a thread-affine lock across suspension and later hangs or fails. Not for all coroutine crashes or choosing lock performance.'
---
# Mutex Held Across co_await
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
This pattern can occur in native application, service, or user-mode driver
code, including UMDF components that use C++ coroutines. Look for a lock
acquired before `co_await` and released after resumption or
coroutine destruction. Mutex ownership belongs to the acquiring thread, not
the coroutine frame. A resumption on another thread can violate that contract.
Even same-thread resumption can create reentrancy or progress problems when
the awaited operation needs a lock the coroutine still holds.
## Workflow
1. Identify the exact lock primitive and acquisition/release scope in source.
Audit every suspension point while the RAII guard or ownership is alive.
2. Establish the acquire and resume threads using trace/source evidence.
Standard mutexes and SRW locks do not provide a universally queryable owner
field; do not fabricate an owning TID from undocumented layouts.
3. Verify the awaiter's resumption contract. C++/WinRT can preserve apartment
context for particular awaitables; `resume_background` intentionally switches.
Do not assume every WinRT awaitable always resumes on a worker or always on
the originating thread.
4. Distinguish wrong-thread release, a dependency cycle, state changed during
suspension, lifetime failure, and unrelated memory corruption.
5. Move the thread-affine lock into synchronous scopes. Revalidate relevant
state after the await rather than treating the pre-await snapshot as current.
If the symptom is general blocking use `windbg-user-wait-chain-analysis`. For damaged
heap objects use `windbg-user-heap-corruption-investigation`. If a recording is available,
`windbg-user-ttd-reverse-debugging-triage` can help establish the ownership timeline.
## Fix pattern
Conceptual sequence, not a promise about any particular scheduler:
```text
under lock:
take a snapshot and its generation
release lock
await work using that snapshot
under lock on the resumed thread:
revalidate generation, lifetime, and assumptions
apply result or explicitly handle a stale/cancelled operation
release lock
```
Use RAII for each synchronous scope. If invariants cannot tolerate unlocking,
redesign the operation or use a specifically designed asynchronous coordination
primitive with cancellation/lifetime rules. Switching to a recursive mutex or
`shared_mutex` does not make a thread-affine lock coroutine-safe.
Do not recommend a blanket mutex-type replacement. Shared locking is a separate
design decision; changing the primitive does not repair suspension ownership.
Keep the object and any captured interfaces alive across asynchronous work.
## Validation
- No thread-affine lock ownership survives a suspension in the corrected path.
- Each awaiter's thread/apartment contract is understood.
- State invariants are revalidated after suspension.
- Cancellation, concurrent mutation, shutdown, and failed awaited work are tested.
- The remedy removes the demonstrated cause, not just an observed exception.
## References
- [Holding a lock across coroutine suspension](https://devblogs.microsoft.com/oldnewthing/20210707-00/?p=105417)
- [C++/WinRT concurrency and asynchronous operations](https://learn.microsoft.com/windows/uwp/cpp-and-winrt-apis/concurrency)
- [Slim reader/writer locks](https://learn.microsoft.com/windows/win32/sync/slim-reader-writer--srw--locks)
## Feedback
Follow `FEEDBACK.md` and report reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-mutex-held-across-co-await` and the package version from `plugin.json`;
no automatic source, dump, or transcript upload.

View File

@@ -0,0 +1,105 @@
---
name: windbg-user-ttd-reverse-debugging-triage
description: 'Use when an app, service, or user-mode driver host TTD recording is available and earlier calls, writes, or lifetimes matter. Not for kernel replay or history from a normal dump.'
---
# TTD Reverse Debugging Triage
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Requirements and scope
Time Travel Debugging records a user-mode process for replay, including an
authorized application, service, or user-mode driver host process. A dump alone
contains no execution timeline. Confirm a valid recording and matching module
symbols before attempting timeline queries. It does not record kernel execution
or automatically include another process's server-side activity.
Recording can change timing, require substantial storage, and capture sensitive
memory. Obtain authorization before capture. Check the installed recorder's help
for supported target, architecture, and options. WinDbg's **Launch executable
(advanced)** / **Record with Time Travel Debugging** flow can record a named
test application without guessing a recorder command.
## Workflow
### 1. Open and index the recording
Open the recorded `.run` file in WinDbg and load public Windows symbols and
matching PDBs for your own binaries.
```text
!tt.index
dx @$cursession.TTD
```
Confirm the timeline range. Indexing and data-model availability depend on
WinDbg/TTD versions; consult the installed help if the command is unavailable.
### 2. Ask a bounded history question
```text
dx @$cursession.TTD.Calls("MyModule!MyFunction")
dx @$cursession.TTD.Memory(<start-address>, <end-address>, "w")
```
Query the known function or exact memory range, then inspect relevant results
and their timeline positions. An empty result can mean unmatched symbols,
uninstrumented execution, or an out-of-range query, not proof of absence.
Use the call query to find allocation/free or module lifetime transitions and
the memory query to locate candidate writes. Account for allocator reuse: the
same virtual address may represent different objects over the recording.
### 3. Seek and inspect state
```text
!tt <position>
k
r
g-
```
Seek to an actual position returned by the query. `g-` continues backward;
use the installed reverse-step controls to refine the search. Capture the
last-good and first-bad states, writer/caller stack, and ownership transition.
Do not equate the last write with the bug until you establish the object's
identity, valid lifetime, intended invariant, and relevant cross-thread order.
### 4. Continue with a shipped investigation
| Evidence | Skill |
|---|---|
| Bad free/write or allocation-boundary violation | `windbg-user-heap-corruption-investigation` |
| Growing allocation/reservation usage | `windbg-user-virtual-memory-exhaustion` |
| Lock survives coroutine suspension | `windbg-user-mutex-held-across-co-await` |
| Blocker or cross-process dependency at the selected moment | `windbg-user-wait-chain-analysis` |
For other user-mode families continue reasoning from the timeline rather than
dispatching to absent skills. For a kernel crash use `windbg-kernel-bugcheck-triage`;
TTD is not a kernel-history substitute.
## Validation
Record the question, trace identity, timeline positions, relevant object
lifetime, and source/stack evidence. Test alternatives and state recording
boundaries. A reproducible timeline proves what occurred in that recording;
it does not establish that instrumentation preserved all production timing.
## References
- [Time Travel Debugging overview](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/time-travel-debugging-overview)
- [TTD data-model queries](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/time-travel-debugging-object-model)
- [TTD extension commands](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/time-travel-debugging-extension-commands)
## Feedback
Follow `FEEDBACK.md` and report a reviewed summary to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-ttd-reverse-debugging-triage` and the package version from
`plugin.json`; never automatically upload a recording or its memory/query
contents.

View File

@@ -0,0 +1,113 @@
---
name: windbg-user-virtual-memory-exhaustion
description: 'Use when a native app, service, or user-mode driver host allocation fails; distinguish VA exhaustion, fragmentation, and commit pressure. Not for managed .NET heap growth, proving a leak from one snapshot, or corruption.'
---
# Virtual Memory Exhaustion
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
Investigate `E_OUTOFMEMORY` (`0x8007000E`), `STATUS_NO_MEMORY` (`0xC0000017`),
`bad_alloc`, or failed heap/virtual allocations in an application, service, or
user-mode driver host (including UMDF). Record the actual API, requested
size/alignment, architecture, flags, and error. Free physical RAM does not rule
out insufficient virtual address space, commit pressure, or applicable limits.
## Workflow
### 1. Examine the process VA map
```text
!address -summary
!address
!heap -s
```
Compare available regions with the attempted allocation's contiguous range and
alignment requirements. Distinguish reserved, committed, free, image, mapped,
stack, and heap ranges. A large reservation consumes VA without committing its
entire range. Heap internals may require more than the user's requested bytes.
Report unavailable pages/map data rather than inferring completeness from a
limited dump.
### 2. Separate pressure mechanisms
| Mechanism | Evidence needed |
|---|---|
| VA exhaustion | Process address range/architecture and little usable free VA |
| Fragmentation | Free space exists, but no suitable contiguous/aligned region |
| System commit pressure | Commit usage/limit near the failure, not just free RAM |
| Process/job memory limit | Actual configured limit and relevant usage/accounting |
| Allocation policy/API failure | API-specific constraints, flags, or allocator policy |
Use contemporaneous system memory counters or an appropriate live/kernel
session for system commit data. A process PEB is not a documented
`MaximumCommit` source. A process's committed bytes alone do not establish a
system-wide or job limit.
For 32-bit targets inspect `/LARGEADDRESSAWARE` and the host architecture;
2 GB versus up to 4 GB depends on those settings. Verify current documented
limits for the target Windows version and architecture instead of applying
one 64-bit limit to every system.
### 3. Identify dominant consumers
```text
!address -f:Heap
!address -f:Stack
!heap -stat -h <heap-address>
```
Use `!address -?` and `!heap -?` for allocator/version-specific support.
Classify dominant heaps, stacks, mappings, images, and reserved arenas.
Large or numerous allocations are not automatically leaks: map them to cache
policy, owners, workload, and expected lifetimes.
### 4. Establish growth with history
Collect authorized time-series counters, repeated comparable snapshots, or
allocation/free tracing across the workload. Compare warm-up with steady-state
behavior and verify whether memory is reclaimed when work finishes.
One snapshot plus process uptime cannot prove a leak rate. For a suitable
user-mode recording use `windbg-user-ttd-reverse-debugging-triage`; for damaged allocations
use `windbg-user-heap-corruption-investigation` instead.
## Fix patterns
- Bound caches by an appropriate size/cost policy and verify eviction.
Define the lifetime of any references returned before eviction.
- Match `VirtualAlloc` reservations with the correct `VirtualFree` release
contract; distinguish decommit from release.
- Use RAII to release resources on all supported exit/error paths.
- Reduce large contiguous allocation requirements where the design permits.
- Do not blindly increase limits or stack reservations before finding the
pressure source, and do not convert a failed allocation into a silent success.
## Validation
Name the failing allocation and pressure mechanism, identify the consumer with
evidence, and exercise the remedy through warm-up, sustained load, and cleanup.
Verify memory remains bounded or the intended allocation succeeds under the
required constraints. Document configured system/job limits separately.
## References
- [Address extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-address)
- [Heap extension](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-heap)
- [Windows memory limits](https://learn.microsoft.com/windows/win32/memory/memory-limits-for-windows-releases)
- [Large-address-aware linker option](https://learn.microsoft.com/cpp/build/reference/largeaddressaware-handle-large-addresses)
- [VirtualFree](https://learn.microsoft.com/windows/win32/api/memoryapi/nf-memoryapi-virtualfree)
## Feedback
Follow `FEEDBACK.md` and submit reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-virtual-memory-exhaustion` and the package version from `plugin.json`;
no automatic dump or memory-content upload.

View File

@@ -0,0 +1,116 @@
---
name: windbg-user-wait-chain-analysis
description: 'Use when an app, service, or user-mode driver host is unresponsive on locks, COM/RPC, I/O, or another process; follow the blocker chain. Not for a crash solely from an exception stack.'
---
# Cross-Process Wait Chain Analysis
**Load `windbg-diagnostic-method` first** if it is not already loaded in this
conversation, and apply it throughout for evidence ranking, hypothesis testing,
confidence calibration, independent review, and report validation. This skill
adds the bug-family-specific commands and evidence requirements.
## Detection
Look for blocked work in an application, service, or user-mode driver host
(including UMDF), and threads in wait, COM, RPC, or I/O paths.
The process displaying the symptom may not own the underlying defect.
Idle worker threads waiting normally are not evidence of a hang.
## Workflow
### 1. Identify the affected operation and its thread
```text
.lastevent
~*kb
!runaway
```
Confirm why the dump was collected. A dump is a snapshot; `.lastevent` does not
by itself certify "hang" or "no crash." Identify the UI/serving thread from
application evidence instead of assuming thread zero is always the UI thread.
If work is spinning rather than blocked, collect appropriate CPU evidence.
### 2. Identify each wait and its owner
Inspect frames around `WaitForSingleObject`, `WaitForMultipleObjects`, COM
send/receive, and RPC calls. Use matching symbols/source for your own proxy,
interface, and server registration to determine what was requested.
For each edge record:
```text
process / thread -> waited resource or request -> owner / serving thread
```
Do not guess a server PID from undocumented private COM layouts. Use available
Wait Chain Traversal, RPC/COM tracing, application correlation IDs, or
registration/process information, and explicitly mark unresolved edges.
### 3. Gather corresponding server evidence
Obtain authorized dumps or live state of the relevant server processes close
enough in time to represent the same operation. Inspect their serving threads.
For kernel context use documented commands such as:
```text
!process 0 7
!thread <ethread>
```
Available user pages and symbol/context support vary by dump type. If the chain
ends in a kernel lock use `windbg-kernel-lock-deadlock-triage`; if blocked I/O is supported
by IRP evidence use `windbg-kernel-irp-lifecycle-triage`. Do not promise process heaps or
user stacks absent from the dump.
### 4. Distinguish a cycle from a slow or missing responder
- **Cycle:** show every required wait/owner edge back to the starting actor.
- **Contention:** a runnable owner may eventually release the resource.
- **Starvation:** queued work cannot obtain execution capacity.
- **Lost completion:** the actor/event expected to unblock the waiter no
longer exists or no path signals it.
- **Slow server:** the endpoint is doing work, blocked on another dependency,
or looping; gather its evidence before blaming the client.
Multiple snapshots or tracing may be needed to distinguish transient waits
from persistent blocking.
## Fix patterns and COM boundaries
A synchronous COM call from an STA can pump messages and permit reentrancy.
It is not automatically a deadlock. Investigate locks held across calls,
callbacks, apartment access, and any non-pumping waits that form an actual
dependency cycle.
Possible remedies include asynchronous APIs, shorter lock scopes, moving
destruction/cross-process calls outside critical sections, and bounded
wait/cancellation protocols where the API supports them. A timeout on the
caller does not cancel server work by itself.
If work moves to another apartment, marshal apartment-bound interfaces, keep
captured state alive, and dispatch UI updates to the correct thread. Merely
capturing a COM pointer and `this` in a worker lambda is not a safe fix.
## Validation
Identify the affected thread, relevant resources and owners, and demonstrated
cycle or deepest supported blocker. Test the proposed remedy under concurrency,
reentrancy, shutdown, and timeout/cancellation. Do not stop at "waiting in RPC."
If the server dump or an owner edge is missing, state the unresolved hypothesis.
## References
- [Wait Chain Traversal](https://learn.microsoft.com/windows/win32/debug/wait-chain-traversal)
- [Processes, threads, and COM apartments](https://learn.microsoft.com/windows/win32/com/processes--threads--and-apartments)
- [Process inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-process)
- [Thread inspection](https://learn.microsoft.com/windows-hardware/drivers/debuggercmds/-thread)
## Feedback
Follow `FEEDBACK.md` and submit only reviewed, sanitized feedback to
[WinDbg-Feedback](https://github.com/microsoft/WinDbg-Feedback/issues).
Include `windbg-user-wait-chain-analysis` and the package version from `plugin.json`; no
automatic capture or public upload of process dumps or full diagnostic
transcripts.