跳转至

Go 语言工具

有一套程序来构建和处理Go源代码。套件中的程序通常由 go 程序调用,而不是直接运行。

运行这些程序的最常见方法是作为 go 程序的子命令,例如 go fmt。像这样运行,该命令对Go源代码的完整包进行操作,go 程序使用包级参数调用基础二进制文件。

这些程序也可以作为独立的二进制文件运行,使用 go 工具子命令(如 go 工具 cgo)使用未修改的参数。对于大多数命令,这主要对调试有用。某些命令,如 pprof,只能通过 go tool 子命令访问。

最后,fmt 和 godoc 命令被安装为普通的二进制文件,称为 gofmt 和 godoc,因为它们的引用次数很多。

单击链接以获取更多文档、调用方法和用法详细信息。

Name Synopsis
go go 程序操作 go 源码,运行其它工具程序。
tool cgo cgo 用于支持 Go 包调用 C 代码。
tool cover cover 是一个程序,用于创建和分析覆盖率分析信息,由 "go test -coverprofile" 生成。
tool fix fix 程序找到使用语言和库的旧功能的 Go 程序,并以较新的 Go 语言重写。
fmt fmt 格式化 go 包,它也可以作为一个独立的 gofmt 命令与更多的通用选项。
tool doc godoc 为 Go 包提取并生成文档。
tool vet vet 检查 Go 源代码并报告可疑的构造,如参数与格式字符串不匹配的Printf调用。
tool asm asm(通常被调用为 go tool asm)将源文件(汇编代码文件)组装到一个对象文件中,该对象文件以参数源文件的基名命名,后缀为.o。然后,可以将对象文件与其他对象组合到包归档文件中。
tool compile compile(通常作为“go tool compile”调用)编译多个文件组成的Go包。然后,写入一个对象文件,以第一个源码文件名的对象文件( .o)。然后,可以将对象文件与其他对象组合到包归档文件中,或者直接传递到链接器(“go tool link”)。如果使用-pack调用,编译器将跳过中间对象文件,直接写入归档文件。生成的文件包含包导出的符号的类型信息,以及包从其他包导入的符号使用的类型信息。因此,在编译P包的客户端C时,不必读取P的依赖项文件,只需读取P的编译输出。
tool link link(通常作为“go tool link”调用)读取包主目录的Go归档文件或对象及其依赖项,并将其组合到可执行二进制文件中。
tool pack pack 是传统 Unix ar 工具的简单版本。
tool pprof pprof 解释和显示 Go 程序的概要文件。
tool test2json Test2json 将 go test 输出转换为机器可读的JSON流。
tool trace trace 是查看跟踪文件的工具。

这是一份简略的清单。有关编译器等的文档,请参阅 完整命令参考

go

bug         start a bug report
build       compile packages and dependencies
clean       remove object files and cached files
doc         show documentation for package or symbol
env         print Go environment information
fix         update packages to use new APIs
fmt         gofmt (reformat) package sources
generate    generate Go files by processing source
get         add dependencies to current module and install them
install     compile and install packages and dependencies
list        list packages or modules
mod         module maintenance
run         compile and run Go program
test        test packages
tool        run specified go tool
version     print Go version
vet         report likely mistakes in packages

go build

  1. -x 列出 build 过程中用到的所有工具,mkdir/gcc等等

  2. -n 不实际编译,仅打印出 build 过程中用到的所有工具

  3. -a 全部重新构建(命令源码文件与库源码文件)

  4. -race 竞争检测

  5. -gcflags="all=-N -l"

    1. -N 取消优化
    2. -l 取消内联
    3. -m 逃逸分析,打印逃逸信息

    4. go build -gcflags=-S fmt 仅打印fmt包的反汇编信息

    5. go build -gcflags=all=-S fmt' 打印fmt以及其依赖包的反汇编信息
  6. go build -buildmode - plugin 编译成.so插件,通过包 plugin 进行打开,获取符号 - c-shared:使用该参数时会生成出来两个文件,一个.so文件,一个.h头文件 ,使用起来就和使用c 生成的库文件和模块文件一样使用。

go run

编译后运行

go get

get 解析并将依赖项添加到当前开发模块,然后生成并安装它们。

  1. -u 更新
  2. -d 仅下载

go test

go tool

  1. go tool asm file 将go汇编文件编译为 object(.o) 文件。

  2. go tool compile file 将go文件编译为 .o 文件。

  3. go tool compile -N -l -S file 将文件编译为汇编代码

    或者使用:go build -gcflags -S x.go

    gcflags == go compile flags

  4. go tool compile:处理go文件,执行词法分析、语法分析、汇编、编译,输出obj文件

  5. go tool asm:处理汇编文件(.s文件),输出obj文件

  6. go tool pack:打包package下的所有obj文件,输出.a文件

  7. go tool link:链接不同package的.a文件,输出可执行文件

  8. go tool objdump:反汇编obj文件

  9. go tool nm:输出obj文件、.a文件或可执行文件中定义的符号

problems

  1. delve and go on grafana codebase error - decoding dwarf section info at offset 0x0: too short 需要重新编译,携带调试信息
  2. 不显示本地变量内容的问题,可以添加 go build 参数: -i -v -gcflags="all=-N -l"
  3. 加快 cockroachdb 的调试速度,将下面的文件 cockroach-v2.1.0/src/github.com/cockroachdb/cockroach/Makefile 修改为 GOFLAGS := -i -a -v -gcflags="all=-N -l"
  4. 不要使用 goland 的 attach 到进程调试方式,非常慢

Go 调试工具

dlv 调试

  • dlv debug ./main.go -- arg1 arg2 自动编译,然后开始调试
  • dlv exec ./main_debug -- arg1 arg2 启动调试,程序需要按-gcflags="all=-N -l"方式编译

基本命令:

help           打印帮助信息
c              继续
n              next
s              step
bt             调用栈
goroutine      切换goroutine
goroutines     显示所有goroutine
b main.go:2    打断点
cond 1 i==2    条件断点(在断点1上使用条件断点)
set            设置变量值
  1. 掌握Debugger(以delve为例)的基本设置与常用命令:单步执行,跳入函数,跳出函数,设置断点,查看变量,查看寄存器,查看调用栈等
  2. attach pid
  3. connect 连接到调试服务器进行调试
  4. dlv core <executable> <core> 打开core文件和关联的可执行程序,检查进程出现core时的状态
  5. dlv debug [package] 编译无优化程序,开始调试
  6. dlv exec 调试已经编译好的程序(需要用参数-gcflags="all=-N -l" 编译调试版本)
  7. dlv test [package] 编译无优化的测试程序,并开始调试
  8. dlv trace [package] regexp 跟踪程序的执行,设置每个匹配的函数一个跟踪点,当跟踪点触发时打印信息。
  9. 调试命令:
    1. args 参考函数参数
    2. break (b) 打断点
    3. breakpoints (bp) 打印所有活跃断点的信息
    4. call
    5. clear 删除断点
    6. clearall 删除多个断点
    7. condition (cond) breakpoint-id x == 4 设置条件断点
    8. deferred 在一个deferred调用中执行命令
    9. disassemble 反汇编
    10. exit quit q
    11. goroutine (gr) 显示或者切换当前的goroutine
    12. goroutines 列出程序的所有goroutines
    13. list
    14. on breakpoint-name or id <command> 断点触发时执行命令
    15. 单步执行(n),跳入函数(s),跳出函数(so),设置断点(b),查看变量(p x),查看寄存器(regs),bt
  10. 通过合理的日志协助调试和定位问题
  11. 掌握pprof、trace工具,定位内存,并发,性能等复杂问题 - go test ./main -bench . 进行基准测试(时间) - go test ./main -bench . -benchmem 进行基准测试(时间和内存) - go tool pprof - go tool trace - GODEBUG=gctrace=1 跟踪gc情况
  12. 掌握core dump文件的生成和解析工具与方法

gdb调试

Go 可以用 gdb 调试:

  1. dbinit中新增行:add-auto-load-safe-path /root/go/go/src/runtime/runtime-gdb.py 或者 source /root/go/go/src/runtime/runtime-gdb.py
  2. b github.com/bitkv/bitkv/pkg/server.(*Server).Get
  3. info goroutines
  4. goroutine 3 bt

远程调试

  1. 启动 dlv 调试服务器,attach 到 go 应用程序 dlv attach 69658 --headless --listen=:2345 --api-version=2

  2. 使用 goland 可以进行远程调试

Go 模块

1. Go 模块介绍

模块是相关 Go 包的集合,作为一个版本化的单元。模块记录依赖关系,并创建可重现的构建过程。

Usage:

go mod <command> [arguments]

The commands are:

download    download modules to local cache
edit        edit go.mod from tools or scripts
graph       print module requirement graph
init        initialize new module in current directory
tidy        add missing and remove unused modules
vendor      make vendored copy of dependencies
verify      verify dependencies have expected content
why         explain why packages or modules are needed

2. 使用

2.1 基本使用

# 前提:已经存在一个 github 下的项目 bitkv

# 将项目下载到任意位置(注意不要放到 $GOPATH 目录下)
git clone github.com/bitkv/bitkv bitkv
cd bitkv

# 初始化
go mod init github.com/bitkv/bitkv

# 自动生成 go.mod go.sum 两个文件
go mod tidy

# 如果不确定为什么会依赖某个模块,可以打开 go.mod 中查看,然后执行 why 命令分析
go mod why github.com/pkg/errors

2.2 GO111MODULE

为了跟老版本兼容,环境变量 GO111MODULE 默认为 auto,意思是如果在 $GOPATH 所在的目录下,则不使用 Go 模块。

如果已经把项目放到$GOPATH所在的任何子目录下,需要设置

export GO111MODULE=on

在非 $GOPATH 所在的子目录下,则不需要设置。

2.3 GOPROXY

由于国内访问部分网站的问题,在 go mod tidy 的过程中,可能会遇到访问 golang.org 等地址超时的问题,可以通过设置代理解决。Go 模块当前已经默认支持代理设置。

export GOPROXY=https://goproxy.cn

2.4 缓存

下载的模块会保存对应版本到 $GOPATH/pkg/mod 目录下。

3. 总结

参考

https://github.com/golang/go/wiki/Modules