GO可以说是近年来最流行的新兴语言之一。 大多数人一看到分布式和大数据就会想到GO。 本文主要是编译go的源码go环境 源码编译,然后搭建gdb的调试环境。
源代码是Google官方的实现的1.10.2版本,不适用于其他版本和gccgo等其他实现,运行环境是CentOS Linux release 7.5.1804.
编译golang源码
go的源码是用go编写的,编译也需要一个可运行的go。
首先我们从官网下载源代码和二进制文件。
注意两个压缩包解压后的文件夹名称都是gogo环境 源码编译,所以不要解压在同一个目录下。 关于go环境的安装,可以查看我之前的一篇文章——这里不再赘述。
我的go环境安装解压路径(就是上面的go二进制文件的解压路径):
/home/james/opt/go
上面的go源码的解压路径:
/home/james/workspace/go_src
为了方便我把解压之后的文件夹重命名为go_src。
编译go之前需要设置环境变量:
GOROOT_BOOTSTRAP是go二进制文件夹所在目录,
GO_GCFLAGS是编译go时使用的参数。
export GOROOT_BOOTSTRAP=~/opt/go
export GO_GCFLAGS="-N -l"
这里的-N参数表示严格禁止优化,-l参数表示严格禁止内联。 Go 在编译目标程序时会嵌入运行时二进制文件。
禁用优化和内联可以使运行时中的函数更易于调试。
一切都规划好后,就可以进入go源码文件夹(/home/james/workspace/go_src),执行all.bash编译:
等待几分钟。 编译结果将位于/home/james/workspace/go_src/bin 下。 请注意,您自己的目录可能与我的不同。 :
调试golang源代码
接下来我们使用gdb进行调试。 我们以如下源码(hello.go)为例:
package main
import "fmt"
func main() {
var c int = 0
a,b := 1,2
c = a + b
fmt.Printf("c : %dn",c);
fmt.Printf("Hello Wroldn")
}
使用以下命令编译源代码。 这里的-l参数的含义和之前一样。 如果需要,还可以添加-N参数:
/home/james/workspace/go_src/bin/go build -gcflags "-l" hello.go
编译完成后,使用gdb运行:
gdb ./hello
Go 中函数符号名称的命名规则是包名称。 函数名,例如main函数的符号名是main.main,运行时newobject的符号名是runtime.newobject。
首先,在main函数上设置断点并运行:
可以看到成功进入了main函数,并且有源码提示。
接下来,按文件名和行号设置断点:
可以看到,在我使用的环境下,gdb可以正常设置断点、单步执行go代码,但是复制的变量输出的值可能是错误的,即使没有开启优化。
总结
目前我已经简单搭建了gdb的调试环境。 经过更多研究后我会添加更多内容。
发表评论