条件断点
背景
查看到delve
这条issues,对于条件断点会导致程序变慢很多
package main
import (
"fmt"
"time"
)
func main() {
sum := int64(0)
start := time.Now()
for value := int64(0); value < 10000; value++ {
sum += value // break, cond 1 value==-1
}
elapsed := time.Since(start)
fmt.Printf("Sum: %d\nTook %s\n", sum, elapsed)
}
上面的循环次数为10000
,花费时间约13s
,而实际直接debug
不下断点时间为21.184µs
(有波动,但是都在100µs
以下)
// 条件debug
dlv debug ~/workspace/method/main.go
Type 'help' for list of commands.
(dlv) b main.go:12
Breakpoint 1 set at 0x4b40f5 for main.main() /home/chainhelen/workspace/method/main.go:12
(dlv) cond 1 value==-1
(dlv) c
Sum: 49995000
Took 13.516143652s
Process 14748 has exited with status 0
(dlv)
// 直接debug
dlv debug ~/workspace/method/main.go
Type 'help' for list of commands.
(dlv) c
Sum: 49995000
Took 21.184µs
Process 15584 has exited with status 0
也就是说中间差了一个毫秒的数量级,1000倍上下的差异
查找原因
在 dlv
项目里面的cmd/dlv/main.go
添加性能分析代码
import _ "net/http/pprof"
// 注意下面代码需要放在 cmds.New(false).Execute() 前面
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
然后安装make install
按照上面的调试方式,在花费时间较长时间点的时候,下载文件http://localhost:6060/debug/pprof/profile?seconds=30
因为是svg格式,可以右键另外标签页打开
其中耗时较大的都是在利用trace
获取register
,尤其是虚拟寄存器fp
;于是尝试写死fp
寄存器的代码,发现实际并没有用到,`debug`是正常运行的,而且时间确实大幅度下降(仍然很慢)