猿问

“go test -cpuprofile”不会生成完整的跟踪

问题


我有一个带有测试套件的 go 包。


当我为此包运行测试套件时,总运行时间约为 7 秒:


$ go test ./mydbpackage/ -count 1

ok      mymodule/mydbpackage    7.253s

但是,当我添加一个-cpuprofile=cpu.out选项时,采样不会覆盖整个运行:


$ go test ./mydbpackage/ -count 1 -cpuprofile=cpu.out

ok      mymodule/mydbpackage    7.029s


$ go tool pprof -text -cum cpu.out

File: mydbpackage.test

Type: cpu

Time: Aug 6, 2020 at 9:42am (CEST)

Duration: 5.22s, Total samples = 780ms (14.95%)     # <--- depending on the runs, I get 400ms to 1s

Showing nodes accounting for 780ms, 100% of 780ms total

      flat  flat%   sum%        cum   cum%

         0     0%     0%      440ms 56.41%  testing.tRunner

      10ms  1.28%  1.28%      220ms 28.21%  database/sql.withLock

      10ms  1.28%  2.56%      180ms 23.08%  runtime.findrunnable

         0     0%  2.56%      180ms 23.08%  runtime.mcall

      ...

查看收集的样本:


# sample from another run :

$ go tool pprof -traces cpu.out | grep "ms "  # get the first line of each sample

      10ms   runtime.nanotime

      10ms   fmt.(*readRune).ReadRune

      30ms   syscall.Syscall

      10ms   runtime.scanobject

      10ms   runtime.gentraceback

      ...

# 98 samples collected, for a total sum of 1.12s

我看到的问题是:由于某种原因,采样分析器停止收集样本,或者在某个时候被阻塞/减速。


语境


go版本是1.14.6,平台是linux/amd64


$ go version

go version go1.14.6 linux/amd64

这个包包含与数据库交互的代码,测试是在一个实时的 postgresql 服务器上运行的。


我尝试过的一件事:t.Skip()内部调用runtime.Goexit(),所以我用t.Skip简单的return;替换了对和变体的调用。但这并没有改变结果。


问题


为什么不收集更多样本?我有一些已知的模式会阻止/减慢采样器,或者提前终止采样器?


喵喔喔
浏览 161回答 1
1回答

猛跑小猪

-cpuprofile创建一个配置文件,其中仅对积极使用 CPU 的 goroutine 进行采样。在我的用例中:我的 go 代码花费大量时间等待 postgresql 服务器的答案。使用 生成跟踪go test -trace=trace.out,然后使用 提取网络阻塞配置文件go tool trace -pprof=net trace.out > network.out会产生更多相关信息。作为参考,除了使用 打开完整跟踪go tool trace trace.out之外,您还可以传递以下值-pprof=:来自go tool trace文档:net:网络阻止配置文件sync:同步阻塞配置文件系统调用:系统调用阻塞配置文件sched:调度程序延迟配置文件
随时随地看视频慕课网APP

相关分类

Go
我要回答