<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>svnscha - kernel</title>
    <subtitle>automating annoying tasks, sharing tips, and embracing less frustration</subtitle>
    <link rel="self" type="application/atom+xml" href="https://svnscha.de/tags/kernel/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://svnscha.de"/>
    <generator uri="https://astro.build/">Astro</generator>
    <updated>2026-08-26T00:00:00+00:00</updated>
    <id>https://svnscha.de/tags/kernel/atom.xml</id>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.1.0</title>
        <published>2026-08-26T00:00:00+00:00</published>
        <updated>2026-08-26T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/mcp-windbg-1-1-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-1-0-release/</id>
        <summary type="html">Support for the 2.x MCP SDK, a new wait_for_break tool, and fixes for 'g' freezing the machine it was supposed to release.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-1-0-release/">&lt;p&gt;Version 1.1.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt; is out. It's the first release since &lt;a href=&quot;/posts/mcp-windbg-1-0-0-release/&quot;&gt;1.0.0&lt;/a&gt;, which was broken on fresh installs for some time.&lt;/p&gt;
&lt;h2 id=&quot;what-happened-101&quot;&gt;What Happened: 1.0.1&lt;/h2&gt;
&lt;p&gt;The dependency was &lt;code&gt;mcp&amp;gt;=1.28.1&lt;/code&gt; with no upper bound. When the MCP Python SDK shipped 2.0.0 - renaming &lt;code&gt;McpError&lt;/code&gt; to &lt;code&gt;MCPError&lt;/code&gt; and dropping the &lt;code&gt;@server.list_tools()&lt;/code&gt; decorator - every fresh install broke at import:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Existing installs worked fine; only new ones broke. That's the worst kind of bug: invisible to anyone who could report it. 1.0.1 capped the requirement at &lt;code&gt;&amp;lt;2.0.0&lt;/code&gt;. Thanks to @aphroteus for the fix and @arjunarjun07 for finding the cause.&lt;/p&gt;
&lt;p&gt;If you're still on 1.0.0, run &lt;code&gt;pip install --upgrade mcp-windbg&lt;/code&gt;. Any &lt;code&gt;pip install &quot;mcp&amp;lt;2&quot;&lt;/code&gt; workaround can go.&lt;/p&gt;
&lt;h2 id=&quot;support-for-the-2x-sdk&quot;&gt;Support for the 2.x SDK&lt;/h2&gt;
&lt;p&gt;A cap is a stopgap, not a fix. 1.1.0 runs on &lt;code&gt;mcp&amp;gt;=2.0.0&lt;/code&gt;: handlers are passed straight to &lt;code&gt;Server(...)&lt;/code&gt; instead of registered via decorators, and they return the SDK's result types (&lt;code&gt;ListToolsResult&lt;/code&gt;, &lt;code&gt;CallToolResult&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Nothing changes for clients - same tools, same schemas, stdio and streamable-http both work as before. Python support is unchanged (the 2.x SDK wants 3.10+, like this project already did).&lt;/p&gt;
&lt;p&gt;Two changes so the next SDK release is boring instead of another five silent weeks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;All runtime dependencies are capped at the next major version.&lt;/strong&gt; Without a ceiling, moving to 2.x would have left the same trap for 3.0.0. Since mcp-windbg is an application, not a library, upper bounds can't conflict with anything downstream - a breaking SDK release just becomes a failing CI run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A weekly canary tests what users actually get.&lt;/strong&gt; CI installed from &lt;code&gt;uv.lock&lt;/code&gt;, so it only tested pinned versions, while real installs resolve whatever the ranges allow. The canary ignores the lock, installs the newest allowed versions, and runs the test suite every Monday. It's scheduled rather than tied to pull requests on purpose: an upstream break should page me, not block someone's unrelated PR.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;wait_for_break&quot;&gt;&lt;code&gt;wait_for_break&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The one new tool. Resume a target with &lt;code&gt;g&lt;/code&gt;, go do something else, then call &lt;code&gt;wait_for_break&lt;/code&gt; to block until it stops again - breakpoint, bugcheck, or CTRL+BREAK. It returns everything the debugger printed along the way.&lt;/p&gt;
&lt;p&gt;If the wait expires, the target keeps running. Waiting never halts your machine behind your back.&lt;/p&gt;
&lt;h2 id=&quot;fixing-g-freezing-the-target&quot;&gt;Fixing &lt;code&gt;g&lt;/code&gt; Freezing the Target&lt;/h2&gt;
&lt;p&gt;This was bad and hid for a while, so let me be honest about it.&lt;/p&gt;
&lt;p&gt;Go-class commands (&lt;code&gt;g&lt;/code&gt;, &lt;code&gt;gh&lt;/code&gt;, &lt;code&gt;gn&lt;/code&gt;, &lt;code&gt;gN&lt;/code&gt;, &lt;code&gt;gc&lt;/code&gt;, &lt;code&gt;gu&lt;/code&gt;) hand control back to the target, after which the debugger stops reading stdin. The server queued an &lt;code&gt;.echo&lt;/code&gt; marker behind the &lt;code&gt;g&lt;/code&gt;, which never got answered - so the command sat until timeout, and the timeout's CTRL+BREAK halted the target again. Ask the machine to run, get it frozen a minute later. The opposite of what you asked for.&lt;/p&gt;
&lt;p&gt;Go-class commands are now sent bare and return immediately. Step commands (&lt;code&gt;p&lt;/code&gt;, &lt;code&gt;t&lt;/code&gt;, &lt;code&gt;pa&lt;/code&gt;, &lt;code&gt;ta&lt;/code&gt;, ...) are unaffected.&lt;/p&gt;
&lt;p&gt;Fixing that exposed several related problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A command right after &lt;code&gt;g&lt;/code&gt; breaks in cleanly.&lt;/strong&gt; No manual &lt;code&gt;send_ctrl_break&lt;/code&gt;, and the target's output isn't thrown away.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A break-in sent immediately after &lt;code&gt;g&lt;/code&gt; no longer gets lost.&lt;/strong&gt; Resuming used to return before the debugger read the &lt;code&gt;g&lt;/code&gt;, leaving a window where a CTRL+BREAK hit the prompt instead of the target. Against a live KDNET target, a break sent with no gap was lost &lt;em&gt;every single time&lt;/em&gt;. The resume is now confirmed consumed before reporting success.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Break-in checks before signaling.&lt;/strong&gt; A CTRL+BREAK aimed at an already-stopped target would queue and re-halt it later. The session now probes for a prompt first and only signals if there's no answer, making speculative &lt;code&gt;send_ctrl_break&lt;/code&gt; calls safe.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;bp nt!X; g&lt;/code&gt; reports whether the breakpoint was set.&lt;/strong&gt; A typo'd symbol now shows up as &lt;code&gt;Couldn't resolve error&lt;/code&gt; instead of an endless wait.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One operation per session at a time.&lt;/strong&gt; &lt;code&gt;wait_for_break&lt;/code&gt; parks on a worker thread while the server keeps answering other requests; a second call on the same session is refused immediately. Closing a session also ends any wait parked on it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kernel sessions over named pipe or serial connect.&lt;/strong&gt; &lt;code&gt;kd&lt;/code&gt; announces those links with a different message than KDNET, and only the latter was matched - so sessions that were actually attached timed out.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Still one line:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Release notes: &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.1.0&quot;&gt;v1.1.0&lt;/a&gt; - Docs: &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/&quot;&gt;svnscha.github.io/mcp-windbg&lt;/a&gt; - Source: &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;github.com/svnscha/mcp-windbg&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;No headline features here. Just a dependency cap, a canary, one new tool, and a long list of places where the debugger and the server disagreed about who was talking. That's what a &lt;code&gt;.1&lt;/code&gt; release should be - especially after a 1.0.0 nobody could install.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If mcp-windbg has helped you, I'd love to hear about it. Open an issue, reach out, or star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository&lt;/a&gt;. Thank you.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>🚀 New Release: mcp-windbg 1.0.0</title>
        <published>2026-07-16T00:00:00+00:00</published>
        <updated>2026-07-16T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/mcp-windbg-1-0-0-release/"/>
        <id>https://svnscha.de/posts/mcp-windbg-1-0-0-release/</id>
        <summary type="html">Kernel debugging, session IDs, and a redesigned tool surface. The first stable release.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/mcp-windbg-1-0-0-release/">&lt;p&gt;I've just released version 1.0.0 of &lt;strong&gt;mcp-windbg&lt;/strong&gt;. Yes, one-point-zero. The headline: &lt;strong&gt;your AI assistant can now debug the Windows kernel.&lt;/strong&gt; The fine print: every tool has a new name, so bring your prompts. Both below.&lt;/p&gt;
&lt;h2 id=&quot;kernel-debugging&quot;&gt;Kernel Debugging&lt;/h2&gt;
&lt;p&gt;Three new tools, &lt;code&gt;open_kd_session&lt;/code&gt;, &lt;code&gt;run_kd_command&lt;/code&gt;, and &lt;code&gt;close_kd_session&lt;/code&gt;, drive &lt;code&gt;kd.exe&lt;/code&gt; against a live kernel target over the connections you would actually use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;KDNET&lt;/strong&gt; (&lt;code&gt;net:port=...,key=...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Named pipes&lt;/strong&gt; (&lt;code&gt;com:pipe,port=\\.\pipe\...&lt;/code&gt;) - the classic VM setup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Serial&lt;/strong&gt; - because sometimes it is 2003 in your lab and that is fine&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Point your assistant at a VM, ask what that driver is up to, and let it run &lt;code&gt;!process&lt;/code&gt;, &lt;code&gt;!irql&lt;/code&gt;, &lt;code&gt;lm&lt;/code&gt;, and friends while you have your coffee.&lt;/p&gt;
&lt;p&gt;A kernel target is not a dump file: break in at the wrong moment and you have halted an entire machine. The tools are built around that reality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sessions arrive already stopped.&lt;/strong&gt; &lt;code&gt;open_kd_session&lt;/code&gt; waits for the connect banner and breaks in for you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Closing resumes the target.&lt;/strong&gt; &lt;code&gt;close_kd_session&lt;/code&gt; sends &lt;code&gt;g&lt;/code&gt; by default; pass &lt;code&gt;resume: false&lt;/code&gt; only if you want the machine frozen on purpose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--kd-path&lt;/code&gt;&lt;/strong&gt; points the server at a specific &lt;code&gt;kd.exe&lt;/code&gt;, the counterpart to &lt;code&gt;--cdb-path&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also two new guided prompts to go with it: &lt;strong&gt;&lt;code&gt;kernel-triage&lt;/code&gt;&lt;/strong&gt; investigates a kernel target (including telling a real bugcheck apart from a plain break-in, and releasing the machine at the end), and &lt;strong&gt;&lt;code&gt;remote-triage&lt;/code&gt;&lt;/strong&gt; does the same for a live user-mode process.&lt;/p&gt;
&lt;h2 id=&quot;session-ids&quot;&gt;Session IDs&lt;/h2&gt;
&lt;p&gt;The other big change: sessions are now first-class. Every &lt;code&gt;open_*&lt;/code&gt; tool returns an opaque &lt;strong&gt;session ID&lt;/strong&gt; (&lt;code&gt;cdb-…&lt;/code&gt; or &lt;code&gt;kd-…&lt;/code&gt;), and &lt;code&gt;run_*&lt;/code&gt;, &lt;code&gt;close_*&lt;/code&gt;, and &lt;code&gt;send_ctrl_break&lt;/code&gt; address a session by that ID. No more implicit sessions, no more addressing by dump path: open first, then talk. Opening the same dump twice gives you two independent sessions.&lt;/p&gt;
&lt;p&gt;The kind is enforced, too: pass a &lt;code&gt;cdb&lt;/code&gt; ID to &lt;code&gt;run_kd_command&lt;/code&gt; and you get an error naming the right tool. That matters more than it sounds when the caller is a model that occasionally guesses.&lt;/p&gt;
&lt;h2 id=&quot;the-breaking-changes&quot;&gt;The Breaking Changes&lt;/h2&gt;
&lt;p&gt;The old names conflated the product (WinDbg) with the engines doing the work (&lt;code&gt;cdb.exe&lt;/code&gt; for user mode, &lt;code&gt;kd.exe&lt;/code&gt; for kernel). That distinction is now load-bearing, so everything got renamed:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0.x&lt;/th&gt;
&lt;th&gt;1.0.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_windbg_dumps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;list_dumps&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;open_windbg_dump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;open_cdb_dump&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;open_windbg_remote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;open_cdb_remote&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;run_windbg_cmd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;run_cdb_command&lt;/code&gt; / &lt;code&gt;run_kd_command&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;close_windbg_dump&lt;/code&gt;, &lt;code&gt;close_windbg_remote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;close_cdb_session&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Also: &lt;code&gt;send_ctrl_break&lt;/code&gt; takes a &lt;code&gt;session_id&lt;/code&gt;, and the &lt;code&gt;connection_type&lt;/code&gt; parameter is gone because the tool name now says which engine you mean. If you have prompts or agent instructions written against the 0.x names, they need updating - that is exactly why this is 1.0.0 and not 0.16.0. The &lt;a href=&quot;https://svnscha.github.io/mcp-windbg/&quot;&gt;docs&lt;/a&gt; are rewritten around the new flow, including a &quot;Debug a kernel target&quot; guide.&lt;/p&gt;
&lt;h2 id=&quot;smaller-but-you-will-notice&quot;&gt;Smaller, But You Will Notice&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Per-call timeouts&lt;/strong&gt;: &lt;code&gt;timeout_seconds&lt;/code&gt; on any &lt;code&gt;open_*&lt;/code&gt; / &lt;code&gt;run_*&lt;/code&gt; overrides that tool's default. Useful when that one &lt;code&gt;!analyze -v&lt;/code&gt; against a 30 GB dump needs its time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A slow command no longer wedges the session.&lt;/strong&gt; On timeout the server breaks in with CTRL+BREAK and resynchronizes, so the session is usable for the next command instead of stranded.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Output goes to the right command.&lt;/strong&gt; Every command waits on its own unique completion marker, so late output from a slow command can never be mistaken for the next one's result.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No more orphaned debuggers.&lt;/strong&gt; &lt;code&gt;cdb.exe&lt;/code&gt; launched via the Microsoft Store aliases spawns a child that a plain terminate left behind, still holding the target. Shutdown now kills the whole process tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Still a one-liner:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; mcp-windbg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Full release notes are on the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg/releases/tag/v1.0.0&quot;&gt;v1.0.0 release page&lt;/a&gt;, and the project lives at &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;github.com/svnscha/mcp-windbg&lt;/a&gt;. A star is always appreciated.&lt;/p&gt;
&lt;h2 id=&quot;one-point-zero&quot;&gt;One-Point-Zero&lt;/h2&gt;
&lt;p&gt;Fourteen months ago this was a &lt;a href=&quot;/posts/ai-meets-windbg/&quot;&gt;weekend experiment&lt;/a&gt;. Today it sits at 1.4k stars and debugs kernels. Calling it 1.0 is a promise more than a milestone: the names are stable now, and breaking changes from here on will be rare and loud.&lt;/p&gt;
&lt;p&gt;Here is to stable.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If mcp-windbg has helped you, I would love to hear about it. Reach out, open an issue, or just star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository&lt;/a&gt;. Thank you all.&lt;/em&gt;&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Introducing Native Windows Debugging for VS Code: Kernel &amp; Remote Debugging</title>
        <published>2026-06-07T00:00:00+00:00</published>
        <updated>2026-06-07T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/native-windows-kernel-remote-debugging-vscode/"/>
        <id>https://svnscha.de/posts/native-windows-kernel-remote-debugging-vscode/</id>
        <summary type="html">Last time I had a proof of concept. This time I closed the gap: remote debugging and Windows kernel debugging, straight from VS Code, powered by the same engine as WinDbg. It's open source and on the Marketplace.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/native-windows-kernel-remote-debugging-vscode/">&lt;h2 id=&quot;remember-the-cliffhanger&quot;&gt;Remember the Cliffhanger?&lt;/h2&gt;
&lt;p&gt;A while back I wrote about &lt;a href=&quot;/posts/the-joy-of-writing-a-debugger-adapter-for-visual-studio-code/&quot;&gt;the joy of writing a debugger adapter for Visual Studio Code&lt;/a&gt;. It started with a simple wish - I just wanted a faster way to remote-debug a service running in a VM - and ended with a working proof of concept: VS Code driving WinDbg through a custom Debug Adapter Protocol implementation.&lt;/p&gt;
&lt;p&gt;But that post ended on an honest note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have not implemented remote debugging or kernel debugging yet, but I now feel ready to take a real shot at both without getting lost in the basics again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well. I took the shot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remote debugging works. Kernel debugging works.&lt;/strong&gt; And the whole thing is now a real, installable VS Code extension: &lt;strong&gt;Native Windows Debugging (dbgeng)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Debug native Windows code - C and C++ programs, services, and even the Windows kernel - straight from Visual Studio Code, using the same engine that powers WinDbg.&lt;/p&gt;
&lt;div style=&quot;position:relative;padding-bottom:56.25%;height:0;overflow:hidden;margin:1.5rem 0;&quot;&gt;
  &lt;iframe style=&quot;position:absolute;top:0;left:0;width:100%;height:100%;border:0;&quot; src=&quot;https://www.youtube-nocookie.com/embed/bEuCPRmjE8o&quot; title=&quot;Native Windows Debugging (dbgeng) for VS Code&quot; loading=&quot;lazy&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;That's the whole pitch in under two minutes. Now let me show you what's behind it.&lt;/p&gt;
&lt;h2 id=&quot;get-it-right-now&quot;&gt;Get It Right Now&lt;/h2&gt;
&lt;p&gt;No waiting, no building from source:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Marketplace:&lt;/strong&gt; &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=svnscha.vscode-dap-dbgeng&quot;&gt;Native Windows Debugging (dbgeng)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href=&quot;https://github.com/svnscha/dap-dbgeng&quot;&gt;github.com/svnscha/dap-dbgeng&lt;/a&gt; (MIT licensed)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href=&quot;https://svnscha.github.io/dap-dbgeng/&quot;&gt;svnscha.github.io/dap-dbgeng&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The adapter is &lt;strong&gt;bundled inside the extension&lt;/strong&gt;, so there's nothing separate to build, download, or point at. Install it, write a &lt;code&gt;launch.json&lt;/code&gt;, press &lt;kbd&gt;F5&lt;/kbd&gt;. That's it.&lt;/p&gt;
&lt;h2 id=&quot;four-ways-to-debug---two-of-them-were-never-possible-before&quot;&gt;Four Ways to Debug - Two of Them Were Never Possible Before&lt;/h2&gt;
&lt;p&gt;VS Code has always had great local debugging for plenty of languages. But the moment you wanted &lt;em&gt;native Windows&lt;/em&gt; remote or kernel debugging, you hit a wall. That stack lives in Visual Studio and WinDbg, not in VS Code - because of course it does.&lt;/p&gt;
&lt;p&gt;This extension closes exactly that gap. One adapter, four scenarios:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Local&lt;/strong&gt; - the debugger starts your program and debugs it from launch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attach&lt;/strong&gt; - connect to a process that's already running, by its PID.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote&lt;/strong&gt; - debug a user-mode process on &lt;em&gt;another&lt;/em&gt; machine via &lt;code&gt;dbgsrv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kernel&lt;/strong&gt; - debug kernel-mode drivers and the OS around them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first two are the comfortable ones. The last two are the gap I set out to close. Let's walk through them.&lt;/p&gt;
&lt;h2 id=&quot;local-the-comfortable-starting-point&quot;&gt;Local: The Comfortable Starting Point&lt;/h2&gt;
&lt;p&gt;Start simple. The debugger launches your program and you step through it like any other debugger in VS Code. It's just a &lt;code&gt;launch.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Debug myapp&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;dbgeng&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;launch&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;program&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;${workspaceFolder}/build/Debug/myapp.exe&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;stopAtEntry&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;program&lt;/code&gt; is the only thing you really have to provide. &lt;code&gt;dbgeng.dll&lt;/code&gt; is found automatically from your installed Windows SDK, so you usually don't even set a path. Set a breakpoint, press &lt;kbd&gt;F5&lt;/kbd&gt;, and you get the full loop: continue, step over, step into, step out, call stack, locals, watch expressions, and a Debug Console that evaluates expressions through the real engine.&lt;/p&gt;
&lt;p&gt;If you use the &lt;strong&gt;CMake Tools&lt;/strong&gt; extension, you can even drop the &lt;code&gt;program&lt;/code&gt; line entirely - the adapter defaults to your selected CMake launch target. Point CMake's debug command at the &lt;code&gt;dbgeng&lt;/code&gt; type and &lt;strong&gt;CMake: Debug&lt;/strong&gt; just works.&lt;/p&gt;
&lt;h2 id=&quot;attach-already-running-just-connect&quot;&gt;Attach: Already Running? Just Connect&lt;/h2&gt;
&lt;p&gt;Sometimes the process is already alive and you don't want to restart it. Attach to it by its process ID:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Attach to myapp&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;dbgeng&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;attach&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;processId&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;12345&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don't know the PID off the top of your head? Set &lt;code&gt;&quot;processId&quot;: &quot;${command:dap-dbgeng.pickProcess}&quot;&lt;/code&gt; and you get a process picker at debug time. Same familiar VS Code interface, with the real Windows debug engine underneath.&lt;/p&gt;
&lt;h2 id=&quot;remote-my-favorite-part&quot;&gt;Remote: My Favorite Part&lt;/h2&gt;
&lt;p&gt;This was the first scenario I implemented: debugging a user-mode process on &lt;strong&gt;another machine&lt;/strong&gt; while keeping the debug engine and symbols on the local system.&lt;/p&gt;
&lt;p&gt;The trick is the Windows process server, &lt;code&gt;dbgsrv&lt;/code&gt;. You run it on the target, and your machine connects to it over TCP (or a named pipe).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On the target&lt;/strong&gt;, start the process server:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cmd&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;dbgsrv -t tcp:port=&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;5005&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;On your machine&lt;/strong&gt;, point a &lt;code&gt;launch.json&lt;/code&gt; at it:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Attach on TARGETPC&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;dbgeng&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;attach&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;processId&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;${command:dap-dbgeng.pickProcess}&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;connectionString&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;tcp:port=5005,server=TARGETPC&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Press &lt;kbd&gt;F5&lt;/kbd&gt;, pick the remote process from the list (the picker now shows processes on the &lt;code&gt;dbgsrv&lt;/code&gt; host), and you're debugging it remotely. The engine and symbols never leave your machine - only the debuggee lives on the other side.&lt;/p&gt;
&lt;p&gt;This is precisely the workflow I wanted at the very beginning: compile locally, deploy to the VM, attach, get back to work. Now it's a one-keystroke thing.&lt;/p&gt;
&lt;h2 id=&quot;kernel-yes-really&quot;&gt;Kernel: Yes, Really&lt;/h2&gt;
&lt;p&gt;And then there's the big one. &lt;strong&gt;Kernel-mode debugging from VS Code.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Kernel debugging is whole-machine, so you need two boxes: a &lt;strong&gt;host&lt;/strong&gt; (VS Code + the adapter) and a &lt;strong&gt;target&lt;/strong&gt; being debugged - almost always a throwaway VM, because kernel debugging halts the entire target at breakpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On the target&lt;/strong&gt;, enable kernel debugging and reboot:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cmd&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;bcdedit&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; /debug on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;bcdedit&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; /dbgsettings &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;net&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; hostip:&amp;lt;HOST-IP&amp;gt; port:50005 key:1.2.3.4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;On the host&lt;/strong&gt;, point a kernel config at it:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Debug driver (KDNET)&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;dbgeng&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;request&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;attach&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;kernel&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;connectionString&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;net:port=50005,key=1.2.3.4&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;kernel: true&lt;/code&gt; flips the adapter into kernel mode and turns &lt;code&gt;connectionString&lt;/code&gt; into a kernel transport. There's no &lt;code&gt;processId&lt;/code&gt; here - the session &lt;em&gt;is&lt;/em&gt; the whole machine. Press &lt;kbd&gt;F5&lt;/kbd&gt;, it connects over KDNET, and breaks at &lt;code&gt;DriverEntry&lt;/code&gt;. From the same editor people keep telling me is &quot;just a text editor.&quot;&lt;/p&gt;
&lt;p&gt;Kernel debugging. Just another breakpoint. That still feels a little unreal to type.&lt;/p&gt;
&lt;p&gt;KDNET isn't the only option, either - the same &lt;code&gt;connectionString&lt;/code&gt; field speaks serial (named pipe), 1394, and USB transports too. Whatever your VM or test box gives you.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;p&gt;A few things changed since the proof of concept, and they're worth a mention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It talks to the engine natively.&lt;/strong&gt; The adapter uses the real DbgEng APIs throughout - &lt;code&gt;IDebugClient&lt;/code&gt;, &lt;code&gt;IDebugControl&lt;/code&gt;, &lt;code&gt;IDebugSymbols&lt;/code&gt;, &lt;code&gt;IDebugSystemObjects&lt;/code&gt;, with &lt;code&gt;IDebugEventCallbacks&lt;/code&gt; and &lt;code&gt;IDebugOutputCallbacks&lt;/code&gt; for events. No fragile text-scraping of WinDbg console output. When the engine knows something, the adapter asks it directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The protocol layer is still generated.&lt;/strong&gt; That code-generation step I was so happy about last time paid off again. &lt;code&gt;src/protocol/&lt;/code&gt; is generated from the official DAP schema, so every request, response, and event stays in lockstep with the spec instead of drifting from hand-written DTOs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The POC grew up - and changed language.&lt;/strong&gt; The original proof of concept was C#. Hardening it into something I'd actually ship meant rebuilding the adapter in &lt;strong&gt;C++20&lt;/strong&gt; (CMake + Ninja, vcpkg manifest mode), sitting much closer to the engine it wraps. That was part of the &quot;harden the rough edges&quot; plan, and it made the kernel and remote work far less painful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It records itself.&lt;/strong&gt; There's a built-in session-trace recorder that doubles as the project's replay-test format. Recorded sessions get replayed against real test debuggees in CI, so the behaviors you see in those videos are the same behaviors the test suite asserts on.&lt;/p&gt;
&lt;h2 id=&quot;an-honest-word-on-scope&quot;&gt;An Honest Word on Scope&lt;/h2&gt;
&lt;p&gt;I'm keeping the same promise I made in the first post: the adapter advertises only what it implements &lt;em&gt;correctly&lt;/em&gt;, rather than dangling buttons that misbehave.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What works today:&lt;/strong&gt; line and conditional breakpoints, step over/into/out, continue, pause, instruction-level stepping in the disassembly view, call stack with delayed frame loading, variables and scopes (including registers), set-variable, expression evaluation in the Watch pane and Debug Console, disassembly view, and clean terminate/disconnect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What's planned but not advertised yet:&lt;/strong&gt; function breakpoints, data breakpoints (watchpoints), hit-conditional breakpoints, logpoints, read/write memory, a modules view, evaluate-on-hover, and hex formatting toggles. The engine can do all of these - the adapter just doesn't expose them yet. The &lt;a href=&quot;https://svnscha.github.io/dap-dbgeng/reference/features/&quot;&gt;features reference&lt;/a&gt; keeps the full, deliberately conservative list.&lt;/p&gt;
&lt;p&gt;And here's the escape hatch: anything the UI doesn't surface, you can usually still do by typing native debugger commands straight into the Debug Console. It's the real engine - it'll answer.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;If you want to try it, the whole loop is about ten minutes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;strong&gt;Native Windows Debugging (dbgeng)&lt;/strong&gt; from the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=svnscha.vscode-dap-dbgeng&quot;&gt;Marketplace&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make sure you have &lt;strong&gt;Debugging Tools for Windows&lt;/strong&gt; (it ships &lt;code&gt;dbgeng.dll&lt;/code&gt;, via the Windows SDK or WDK installer). The adapter finds it automatically.&lt;/li&gt;
&lt;li&gt;Drop a &lt;code&gt;dbgeng&lt;/code&gt; configuration into &lt;code&gt;.vscode/launch.json&lt;/code&gt; - pick the scenario from above.&lt;/li&gt;
&lt;li&gt;Set a breakpoint, press &lt;kbd&gt;F5&lt;/kbd&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href=&quot;https://svnscha.github.io/dap-dbgeng/getting-started/&quot;&gt;Getting Started guide&lt;/a&gt; walks through it in detail, and each scenario has its own page in the docs.&lt;/p&gt;
&lt;h2 id=&quot;your-turn&quot;&gt;Your Turn&lt;/h2&gt;
&lt;p&gt;This is open source, and it's at the stage where real-world usage is the most valuable thing it can get. So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;Star it&lt;/strong&gt; on &lt;a href=&quot;https://github.com/svnscha/dap-dbgeng&quot;&gt;GitHub&lt;/a&gt; if it's useful to you.&lt;/li&gt;
&lt;li&gt;🐛 &lt;strong&gt;Report a bug&lt;/strong&gt; through the &lt;a href=&quot;https://github.com/svnscha/dap-dbgeng/issues&quot;&gt;issue tracker&lt;/a&gt; - the templates tell you what to include.&lt;/li&gt;
&lt;li&gt;🔧 &lt;strong&gt;Contribute&lt;/strong&gt; if you're into native Windows debugging internals; see &lt;code&gt;CONTRIBUTING.md&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Last time I closed with &quot;I just want to remote debug a service on a VM.&quot; That was the entire ambition.&lt;/p&gt;
&lt;p&gt;It turned into DAP, a code generator, a &lt;code&gt;dbgeng&lt;/code&gt; wrapper, a pile of state-machine bugs - and now remote debugging, kernel debugging, a published extension, and a documentation site.&lt;/p&gt;
&lt;p&gt;The gap between &quot;VS Code can't do native Windows kernel and remote debugging&quot; and &quot;actually, now it can&quot; is closed. With the same engine that powers WinDbg, sitting quietly behind the editor you already use every day.&lt;/p&gt;
&lt;p&gt;And yes - it still started with &quot;I just want to remote debug a service on a VM.&quot;&lt;/p&gt;
&lt;h2 id=&quot;ps---one-more-thing-about-those-videos&quot;&gt;P.S. - One More Thing About Those Videos&lt;/h2&gt;
&lt;p&gt;While you're here: how did you actually like the videos? Be honest.&lt;/p&gt;
&lt;p&gt;Because here's the fun part - this is the first time I generated end-to-end videos, all the way from Claude to YouTube. No editing suite, no timeline scrubbing, no manual voiceover takes. Just prompting and vibing until it looked right.&lt;/p&gt;
&lt;p&gt;The stack, if you're curious:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.remotion.dev/&quot;&gt;Remotion&lt;/a&gt;&lt;/strong&gt; for the video itself - everything you see is React, rendered to MP4. Code as video turns out to be a really nice fit for the &quot;iterate fast&quot; loop.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My &lt;a href=&quot;/posts/dgx-spark-hello-word/&quot;&gt;DGX Spark&lt;/a&gt;&lt;/strong&gt; doing the heavy lifting locally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/OpenMOSS/MOSS-TTS&quot;&gt;MOSS-TTS&lt;/a&gt;&lt;/strong&gt; for the voice. And here's a little detour: I first deep-cloned &lt;em&gt;my own&lt;/em&gt; voice. The result was genuinely impressive - but not quite perfect, and the &quot;almost me&quot; uncanny gap bugged me more than I expected. So I switched to a fully synthesized voice instead, and I was happier with that than with a not-quite-right clone of myself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think that's pretty cool. A little surreal, honestly. The same &quot;describe what you want, iterate, ship&quot; loop that built the debugger also produced the launch video for it.&lt;/p&gt;
&lt;p&gt;So let me know what you think - of the extension &lt;em&gt;and&lt;/em&gt; of the videos. What worked, what felt off, what you'd want next. There's no comment box here, so just &lt;strong&gt;hit me up&lt;/strong&gt; (&lt;a href=&quot;https://www.linkedin.com/in/svnscha/&quot;&gt;LinkedIn&lt;/a&gt; or &lt;a href=&quot;https://github.com/svnscha/&quot;&gt;GitHub&lt;/a&gt;) or open an issue. I'm genuinely curious.&lt;/p&gt;
</content>
    </entry>
</feed>
