[DotNet] build 与 trace 时候的一些编译选项: 如何编译二进制程序才能使用 dotnet-trace 采集到 cpu profile
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
我希望 dotnet 可以像 golang 那么方便,用浏览器连接到 http 端口,就能进行 trace ,采集 cpu profile 数据,并展示火焰图。
一开始我打算自建一个在线 debug 的 all-in-one 镜像来解决这个问题:see https://github.com/ahfuzhang/CSharpDbgContainer
实际使用中发现,如果不使用 dotnet xxx.dll 或者 dotnet run --project xxx.csproj 的模式,如果直接编译为二进制,使用 dotnet-trace 就无法采集到 cpu profile 数据。
究竟哪几个参数影响了 dotnet-trace 采集数据?下面是我实验得到的结论:
dotnet publish MyProj.csproj \
-c Release -r linux-x64 \
-p:PublishAot=false \
-p:StripSymbols=false \
-p:EventSourceSupport=true \
-p:PublishReadyToRun=true \
--self-contained false \
-o ./build/MyProj/linux/amd64/
重点是以下参数:
-p:EventSourceSupport=true支持 dotnet 内部的 event 机制-p:PublishReadyToRun=true提前编译,启动/吞吐更接近“发布体验”,但仍然是 CoreCLR(JIT runtime),dotnet-trace cpu-sampling 这条链路通常能工作。-p:PublishAot=false关闭 Ahead-of-Time 功能-p:PublishAot=true的作用是:在 dotnet publish 时启用 Native AOT(Ahead-of-Time)发布,把你的 .NET 应用 提前编译成原生机器码的单文件可执行程序(native binary),运行时不再依赖 JIT 编译。也就是说,它走的是 “本机原生程序 + 精简运行时” 的部署形态,而不是传统的 CoreCLR/JIT 形态。
按照以上参数,就能在使用 dotnet-trace 的时候正确采集 cpu profile 数据
dotnet-trace 的命令行如下:
dotnet-trace collect --profile dotnet-sampled-thread-time --duration 00:00:${seconds} --format Speedscope -p ${processId} -o ${outputTracePath}
另外,推荐的参数是:
-p:StripSymbols=false保留符号--self-contained false不拷贝系统的 dll,看起来清爽一些-p:EmbedAllSources=true把源码编译到符号中,便于调试

浙公网安备 33010602011771号