原文来自知乎专栏:zhuyasen - Go有引力

升级到 Go 1.25 之后,在 Windows 上编译出来的 .exe 双击却提示 「此应用无法在你的电脑上运行」?明明 Go 1.24 还好好的,到底发生了什么?答案就藏在一个叫 DWARF v5 的调试信息格式里。


根本原因

Go 1.25 开始,官方默认启用了 dwarf5 实验性功能,编译生成可执行文件时会使用 DWARF v5 调试信息格式

这本身是为了优化调试体验(更紧凑的结构、支持更多元数据),但 Windows PE 格式对 DWARF 的支持非常有限。在 部分 Windows 版本(尤其是启用了 SmartScreen / Core Isolation 的 Windows 11 环境)中,系统加载器或安全组件会直接拒绝包含 DWARF v5 section 的 EXE 文件,导致上述错误。


DWARF 是什么?

DWARF 是一种标准的调试信息格式,用于在二进制文件中存储:

  • 源代码行号
  • 变量名和类型
  • 函数符号
  • 栈帧和调试符号表

Go 在编译时把这些信息写入 .debug_* 段(sections)里,运行时并不读取这些调试段——它们纯粹是给调试器(GDB / Delve)使用的。


DWARF v4 vs v5 对比

对比项DWARF v4DWARF v5
引入时间Go ≤ 1.24 默认Go ≥ 1.25 默认
文件体积略大更紧凑(结构优化)
调试信息格式较旧,兼容性好新格式,支持更多元数据
调试器支持GDB / Delve 都支持需新版 GDB / Delve
对运行性能影响
Windows 兼容性✅ 稳定❌ 可能导致「此应用无法在你的电脑上运行」

DWARF v5 改善的是调试体验,而非运行性能。遗憾的是,某些 Windows 安全机制对新格式不买账。


解决方法

临时方案(当次构建)

set GOEXPERIMENT=nodwarf5
go build .

永久方案(推荐)

go env -w GOEXPERIMENT=nodwarf5

这会告诉 Go:不要使用 DWARF v5,回退到 DWARF v4 调试信息格式

设置后,编译产物恢复兼容性,.exe 可以在 Windows 上正常加载执行。


三种情况对比

项目Go 1.24.xGo 1.25.x(默认)Go 1.25.x + nodwarf5
调试信息格式DWARF v4DWARF v5DWARF v4
Windows 构建兼容性✅ 稳定❌ 可能报错✅ 稳定
链接方式内部链接器外部链接器外部或内部均可
推荐用途全面兼容实验性推荐作为默认设置

Go 1.25.x 其他实验性功能

Go 1.25 同期还引入了几个值得关注的 GOEXPERIMENT 选项:

功能说明
greenteagc新的垃圾回收器,旨在降低高并发、小对象频繁分配服务中的 GC 开销
jsonv2encoding/json 包的新实现,提供更快的解码速度
nodwarf5禁用 DWARF v5 调试信息,回退到 v4,解决 Windows 兼容性问题

可以同时启用多个:

GOEXPERIMENT=greenteagc,jsonv2 go build .

小结

  • Go 1.25 默认启用 DWARF v5,导致部分 Windows 环境无法运行编译产物。
  • 影响范围:启用了 SmartScreen / Core Isolation 的 Windows 11,以及部分使用外部链接器的场景。
  • 一行命令搞定go env -w GOEXPERIMENT=nodwarf5
  • 这是调试信息格式的兼容性问题,与运行性能无关,设置 nodwarf5 没有性能损失。

如果你的团队有 Windows 发布需求,建议在 CI/CD 流程中统一加上此环境变量,避免发布后出现兼容性问题。