大纲
Golang tools
nm
compile
objdump
pprof
trace
单元测试
执行单元测试
统计代码覆盖率
程序 Debug
dlv 调试用法
gdb 调试
小技巧
不知道怎么断点函数?
不知道调用上下文?
不知道怎么开启 pprof ?
为什么有时候单点调试的时候,总是非预期的执行代码?
总结
本文专注 golang debug 的一些技巧应用,以及相关工具的实用用法,再也不用怕 golang 怎么调试。golang 作为一门现代化语音,出生的时候就自带完整的 debug 手段:
- golang tools 是直接集成在语言工具里,支持内存分析,cpu分析,阻塞锁分析等;
- delve,gdb 作为最常用的 debug 工具,让你能够更深入的进入程序调试;
- delve 当前是最友好的 golang 调试程序,ide 调试其实也是调用 dlv 而已,比如 goland;
- 单元测试的设计深入到语言设计级别,可以非常方便执行单元测试并且生成代码覆盖率;
Golang tools
go tool
root@ubuntu:~# go tooladdr2lineasmbuildidcgocompilecoverdistdocfixlinknmobjdumppackpproftest2jsontracevet
我这里专注挑选几个 debug 常用的:
nmobjdump
nm
查看符号表的命令,等同于系统的 nm 命令,非常有用。在断点的时候,如果你不知道断点的函数符号,那么用这个命令查一下就知道了(命令处理的是二进制程序文件)。
# exmple 为你编译的二进制文件go tool nm ./example
第一列是地址,第二列是类型,第三列是符号:
compile
汇编某个文件
go tool compile -N -l -S example.go
你就能看到你 golang 语言对应的汇编代码了(注意了,命令处理的是 golang 代码文本),酷。
objdump
objdump
go tool objdump example.ogo tool objdump -s DoFunc example.o // 反汇编具体函数
汇编代码这个东西在 90% 的场景可能都用不上,但是如果你处理过 c 的程序,在某些特殊场景,通过反汇编一段逻辑来推断应用程序行为将是你唯一的出路。因为线上的代码一般都是会开启编译优化,所以这里会导致你的代码对不上。再者,线上不可能让你随意 attach 进程,很多时候都是出 core 了,你就只有一个 core 文件去排查。
pprof
pprof 支持四种类型的分析:
- CPU :CPU 分析,采样消耗 cpu 的调用,这个一般用来定位排查程序里耗费计算资源的地方;
- Memroy :内存分析,一般用来排查内存占用,内存泄露等问题;
- Block :阻塞分析,会采样程序里阻塞的调用情况;
- Mutex :互斥锁分析,采样互斥锁的竞争情况;
我们这里详细以内存占用分析举例(其他的类似),pprof 这个是内存分析神器。基本上,golang 有了这个东西,99% 的内存问题(比如内存泄露,内存占用过大等等)都是可以非常快的定位出来的。首先,对于 golang 的内存分析(或者其他的锁消耗,cpu 消耗)我们明确几个重要的点:
- golang 内存 pprof 是采样的,每 512KB 采