dotnet-dump是.net 6+线上内存问题最轻量可靠的首选诊断工具,可跨平台收集分析内存快照,但需确保运行时版本匹配、架构一致且启用complus_dbgenableminidump环境变量。

线上程序出问题,Visual Studio 本身不直接运行在线上环境,排查必须靠日志、远程调试能力、以及部署产物的可验证性。核心思路是:把线上行为“拉回本地可观察范围”,而不是在服务器上瞎猜。
看 ILogger 日志是否真实落地且含关键上下文
很多项目只配置了 Console 或 Debug 输出,但线上没开控制台、也没连调试器,日志就彻底消失。确认以下几点:
-
appsettings.Production.json中是否启用了文件或云日志提供程序(如File、ApplicationInsights、Serilog.Sinks.File) - 日志级别是否设为
Warning或更低——Error级别可能漏掉前置异常堆栈 - 是否在异常捕获处显式调用
logger.LogError(ex, "message")?仅logger.LogError("message")会丢掉堆栈 - 检查日志路径权限:IIS 应用池身份、Windows 服务登录账户、Docker 容器内用户,是否对日志目录有写权限
用 dotnet-dump 抓取线上进程内存快照
当程序卡死、CPU 持续 100%、或偶发崩溃但无日志时,dotnet-dump 是最直接的证据来源。它不要求源码或符号文件,只要运行的是 .NET 6+:
Visual Studio 18.8.1 官方固定版本安装引导程序,当前条目使用微软发布历史中的 Professional Web Installer,适合旧项目兼容、环境回退、复现特定构建链和排查版本差异等场景。
- 在目标服务器上执行:
dotnet-dump collect -p <pid></pid>(先用dotnet-trace ps找 PID) - 生成的
.dmp文件可拷贝到本地 Visual Studio(2022 v17.4+),用【调试】→【窗口】→【诊断工具】→【转储调试】打开 - 重点关注:
Threads视图看线程阻塞点、Call Stack看谁在死循环、Modules看是否有加载失败的程序集 - 注意:若 dump 中看不到源码行号,说明线上未部署
.pdb文件,或 PDB 路径与源码路径不匹配
确认发布产物是否和本地调试构建完全一致
“本地能跑,线上挂”八成是发布环节出了岔子。比对以下三项:
- 发布命令是否加了
--configuration Release和--self-contained false?后者若为true会导致体积暴涨且 runtime 版本锁定 - 检查
bin/Release/net8.0/publish/下是否存在缺失的.dll(尤其是 NuGet 包中带runtimes/子目录的 native 依赖) - 运行
dotnet --list-runtimes确认服务器安装的 .NET Runtime 版本 ≥ 项目目标框架;例如项目是net8.0,但服务器只有8.0.0,而某包依赖8.0.4的修复,就会静默失败 - ASP.NET Core 项目要检查
web.config(IIS)或nginx.conf(反向代理)是否转发了X-Forwarded-For等头,否则HttpContext.Connection.RemoteIpAddress可能全是127.0.0.1
远程调试前先验证 vsdbg 是否已就位
Visual Studio 远程调试不是“连上就能断”,它依赖一个叫 vsdbg 的跨平台调试代理。常见失败点:
- 线上服务器没装
vsdbg:执行curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg - 防火墙拦了端口:默认监听
4022,需开放 TCP 入站规则 - 权限问题:Linux 上用
sudo启动vsdbg,但应用进程是普通用户,调试器无法 attach - 启动命令写错:正确格式是
~/vsdbg/vsdbg --interpreter=vscode --port 4022,少参数或路径错都会静默退出 - 别忘了在 VS 里选对调试类型:【调试】→【附加到进程】→ 选择 “Linux” 或 “.NET Core” 类型,而非默认的 “Managed (CoreCLR)”
真正棘手的线上问题,往往卡在“日志没打全、dump 看不懂、远程连不上”的三重嵌套里。优先确保日志能落盘且含异常堆栈,这一步省下的时间,远超后面所有操作的总和。










