需要在服务添加监听的pprof端口:
import (
"net/http"
_ "net/http/pprof"
)
go func() {
log.Println(http.ListenAndServe("localhost:"+os.Getenv("PORT"), nil))
}()
查看进程内存运行信息:
$ go tool pprof <http://localhost>:$PORT/debug/pprof/heap
查看30秒内cpu运行信息:
$ go tool pprof <http://localhost>:$PORT/debug/pprof/profile?seconds=30
查看goroutine阻塞信息:
$ go tool pprof <http://localhost>:$PORT/debug/pprof/block
查看5秒钟内的trace跟踪信息:
$ wget <http://localhost>:$PORT/debug/pprof/trace?seconds=5
查看mutex的holder信息:(需要在代码添加runtime.SetMutexProfileFraction
)
$ go tool pprof <http://localhost:6060/debug/pprof/mutex>
使用pprof profile时经常会输出以下信息:
其中这几列的含义:
根据进程号查看系统调用(mac下使用dtruss):
$ strace -f -p $PID
gdb调试(go build时候需要保留符号信息):
$ gdb --pid=$PID $BINARY_FILE
(gdb) info goroutine //查看所有goroutine信息
(gdb) goroutine $GOROUTINE_ID bt //查看goroutine backtrace调用堆栈
(gdb) goroutine $GOROUTINE_ID frame //查看goroutine栈帧信息
gdb导出core dump文件:
(gdb) gcore
使用dlv分析core文件:
$ dlv core $BINARY_FILE $CORE_FILE
启动dlv api服务:
$ dlv core $BINARY_FILE $CORE_FILE --listen :11111 --headless --log
获取goroutine 列表:
$echo -n '{"method":"RPCServer.ListGoroutines","params":[],"id":2}' | nc -w 1 localhost 11111 > list_goroutines.json
分类统计goroutine列表:
$ jq -c '.result[] | [.userCurrentLoc.function.name, .userCurrentLoc.line]' list_goroutines.json | sort | uniq -c
attach到运行的go进程:
$ dlv attach $PID
A SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal causes the program to exit with a stack dump.
使进程退出并打印堆栈:
$ kill -SIGQUIT $PID