<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Windows on CAO ZUOHUA</title><link>https://caozuohua.github.io/tags/windows/</link><description>Recent content in Windows on CAO ZUOHUA</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 03 Nov 2026 22:00:00 +0800</lastBuildDate><atom:link href="https://caozuohua.github.io/tags/windows/index.xml" rel="self" type="application/rss+xml"/><item><title>系统崩溃归因：从内核到内存的五层收敛法</title><link>https://caozuohua.github.io/posts/2026-11-03-crash-analysis-five-layers/</link><pubDate>Tue, 03 Nov 2026 22:00:00 +0800</pubDate><guid>https://caozuohua.github.io/posts/2026-11-03-crash-analysis-five-layers/</guid><description>&lt;h1 id="系统崩溃归因从内核到内存的五层收敛法"&gt;系统崩溃归因：从内核到内存的五层收敛法&lt;/h1&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;导语：崩溃分析真正的工作量不在「找到崩溃的那个函数」，而在证明它不是根因。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;崩溃报告给出的，几乎总是&lt;strong&gt;发现故障的位置&lt;/strong&gt;，而不是&lt;strong&gt;造成故障的位置&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;内核是个诚实的证人，但它的证词有偏差：它只在踩到非法内存的那一刻报警。而那块内存可能几毫秒前、也可能十几分钟前就被别人写坏了；那个对象可能早已被回收，指针只是还挂在某个链表上。所以崩溃点天生在下游，根因在上游，两者之间隔着一段时序。&lt;/p&gt;&#10;&lt;p&gt;这决定了排查的基本形状：不是去找「谁崩了」，而是沿时间往回退，直到找到一个能被证据钉住、又能被实验证伪的环节。&lt;/p&gt;&#10;&lt;p&gt;下面这套分层方法，是我在一次真实的蓝屏排查中逐步磨出来的。它不是检查清单的堆叠，而是一条证据粒度越来越细的收敛链。&lt;/p&gt;&#10;&lt;h2 id="五层漏斗每层只回答一个问题"&gt;五层漏斗：每层只回答一个问题&lt;/h2&gt;&#10;&lt;p&gt;层与层之间不是并列关系，而是&lt;strong&gt;上下游&lt;/strong&gt;关系。上层的产物是下层的输入，判据是「是否产出一个能被下一层消费的锚点」。没有锚点的层，等于没做。&lt;/p&gt;&#10;&lt;div class="cr-fig"&gt;&#10;&lt;style&gt;&#10;.cr-fig{margin:30px 0}&#10;.cr-fig svg{display:block;width:100%;height:auto}&#10;.cr-cap{font-size:13px;color:#6c757d;text-align:center;margin-top:10px;line-height:1.6}&#10;&lt;/style&gt;&#10;&lt;svg viewBox="0 0 680 452" width="100%" role="img" xmlns="http://www.w3.org/2000/svg"&gt;&#10;&lt;title&gt;崩溃分析的五层收敛漏斗&lt;/title&gt;&#10;&lt;desc&gt;从内核日志、调用栈、模块归属、驱动特征到内存机理，逐层把嫌疑集合收窄，每层产出一个供下一层消费的锚点。&lt;/desc&gt;&#10;&lt;rect x="135" y="24" width="430" height="72" rx="10" fill="#f8f9fa" stroke="#dee2e6" stroke-width="0.5"/&gt;&#10;&lt;text x="350" y="48" text-anchor="middle" dominant-baseline="central" font-size="14" font-weight="500" fill="#212529"&gt;L1 内核层 · kernel&lt;/text&gt;&#10;&lt;text x="350" y="68" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;问：崩在什么上下文、什么错误类型&lt;/text&gt;&#10;&lt;text x="350" y="86" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;出：错误性质 + 故障 IP + 非法地址&lt;/text&gt;&#10;&lt;rect x="155" y="108" width="390" height="72" rx="10" fill="#f8f9fa" stroke="#dee2e6" stroke-width="0.5"/&gt;&#10;&lt;text x="350" y="132" text-anchor="middle" dominant-baseline="central" font-size="14" font-weight="500" fill="#212529"&gt;L2 调用栈 · backtrace&lt;/text&gt;&#10;&lt;text x="350" y="152" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;问：谁调用谁、路径是怎么走过来的&lt;/text&gt;&#10;&lt;text x="350" y="170" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;出：一条方向 + 最深的外部帧&lt;/text&gt;&#10;&lt;rect x="175" y="192" width="350" height="72" rx="10" fill="#f8f9fa" stroke="#dee2e6" stroke-width="0.5"/&gt;&#10;&lt;text x="350" y="216" text-anchor="middle" dominant-baseline="central" font-size="14" font-weight="500" fill="#212529"&gt;L3 模块层 · module&lt;/text&gt;&#10;&lt;text x="350" y="236" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;问：这个地址属于哪个模块&lt;/text&gt;&#10;&lt;text x="350" y="254" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;出：具名模块，或「全部在内核内」&lt;/text&gt;&#10;&lt;rect x="193" y="276" width="314" height="72" rx="10" fill="#f8f9fa" stroke="#dee2e6" stroke-width="0.5"/&gt;&#10;&lt;text x="350" y="300" text-anchor="middle" dominant-baseline="central" font-size="14" font-weight="500" fill="#212529"&gt;L4 驱动层 · driver&lt;/text&gt;&#10;&lt;text x="350" y="320" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;问：它为何在此刻、此负载下出错&lt;/text&gt;&#10;&lt;text x="350" y="338" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#6c757d"&gt;出：可证伪的缺陷假设&lt;/text&gt;&#10;&lt;rect x="208" y="360" width="284" height="72" rx="10" fill="#fdf4f4" stroke="#e8cccc" stroke-width="0.5"/&gt;&#10;&lt;text x="350" y="384" text-anchor="middle" dominant-baseline="central" font-size="14" font-weight="500" fill="#8a2f2f"&gt;L5 内存层 · memory&lt;/text&gt;&#10;&lt;text x="350" y="404" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#a05050"&gt;问：这些字节是被谁改坏或回收的&lt;/text&gt;&#10;&lt;text x="350" y="422" text-anchor="middle" dominant-baseline="central" font-size="12" fill="#a05050"&gt;出：破坏者 ≠ 受害者&lt;/text&gt;&#10;&lt;/svg&gt;&#10;&lt;div class="cr-cap"&gt;图 1 · 每层只承担一个问题，且必须交付一个可被下层消费的锚点&lt;br&gt;越往下越接近机理，也越贵 —— 上层没收敛就别急着往下跳&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;在进入 L1 之前，还有一件成本最低、收益最高的事。&lt;/p&gt;</description></item></channel></rss>