Source Generator 不能直接 F5 调试,因其在编译期运行于 csc.exe 进程内、无独立入口点;需 Attach 到 csc.exe 并确保 Debug 配置与完整调试符号,配合 MSBuild 日志验证加载、或用 Debugger.Launch() 快速确认执行。

Source Generator 调试为什么不能直接 F5?
因为 Source Generator 在编译期运行,不是普通可执行程序,没有入口点,Visual Studio 或 dotnet build 不会把它当独立进程启动。你加断点、按 F5,它根本不会命中——它跑在 csc.exe(C# 编译器)进程里,而且是跨进程、无调试符号加载的。
用 Attach to Process 强制挂载调试器
这是最可靠、最常用的调试方式。关键在于:必须在编译触发前就 attach 到正确的进程,并确保生成器代码已带调试符号(Debug 配置 + GenerateFullDebugSymbols)。
- 在 Source Generator 项目中,确认
.csproj包含:<PropertyGroup> <Configuration>Debug</Configuration> <GenerateFullDebugSymbols>true</GenerateFullDebugSymbols> <DebugType>portable</DebugType> </PropertyGroup>
- 在调用方项目(即引用该 generator 的项目)中,右键 → “设为启动项目”,然后按
Ctrl+F5(不调试启动),让 VS 启动一个空壳进程(避免提前编译) - 在 VS 中:菜单栏 → “调试” → “附加到进程”,勾选“显示所有用户的进程”,查找并选中
csc.exe(注意:可能有多个,优先选命令行含/analyzer:或你 generator DLL 路径的那个) - 在 generator 代码中打上断点(比如
Execute方法),再执行dotnet build或 Ctrl+Shift+B,断点就会被命中
启用 MSBuild 详细日志定位执行时机
有时候 attach 失败,是因为没抓到对的 csc.exe 实例,或者 generator 根本没被加载。这时要看 MSBuild 是否真把 analyzer 加进去了。
- 在调用方项目目录下运行:
dotnet build -v:detailed > build.log 2>&1 - 打开
build.log,搜索Analyzers或你 generator 的 DLL 名,确认类似这一行出现:Using analyzers: C:\path\to\YourGenerator.dll
- 如果没看到,检查
ProjectReference是否用了OutputItemType="Analyzer",或是否漏了<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
用 Console.WriteLine + Debugger.Launch() 快速验证流程
在开发早期,不想反复 attach,可以用“弹窗式调试”快速确认 generator 是否被调用、参数是否符合预期。
- 在
Execute方法开头加:if (!Debugger.IsAttached) Debugger.Launch(); // 运行时弹出 VS 选择框 Console.WriteLine($"Executing for {context.Compilation.AssemblyName}"); - 注意:
Debugger.Launch()只在 Windows 上有效;Linux/macOS 可改用System.Diagnostics.Process.Start("dotnet", "trace collect --process-id ...")配合日志,但不如前者直接 - 此方式适合单次验证,频繁使用会导致每次编译都弹窗,建议配合
#if DEBUG条件编译
真正难的不是打断点,而是理解 generator 的生命周期绑定在编译器 pipeline 的哪个阶段——它没有“重试”“热重载”概念,改完代码必须 clean + rebuild 调用方项目,否则旧缓存的 generator 实例可能还在运行。别信 IDE 的“自动刷新”。










