GO可以说是近几年最热门的新兴语言之一了, 一般人看到分布式大数据就会想到GO,
这个系列的文章会通过研究golang的源代码来分析内部的实现原理,
和CoreCLR不同的是, golang的源代码已经被很多人研究过了, 我将会着重研究他们未提到过的部分.

另一点和CoreCLR不同的是, golang的源代码非常易懂, 注释也非常的丰富,
很明显Google的工程师在写代码的时候有考虑其他人会去看这份代码.

尽管代码非常易懂, 研究它们还是需要实际运行和调试才能得到更好的理解,
这个系列分析的golang源代码是Google官方的实现的1.9.2版本, 不适用于其他版本和gccgo等其他实现,
运行环境是Ubuntu 16.04 LTS 64bit.

编译golang源代码

go的源代码是用go写的, 编译也需要一个可运行的go.
首先我们从官网下载源代码和二进制文件.

go1.9.2.src.tar.gz
go1.9.2.linux-amd64.tar.gz

注意两个压缩包解压出来文件夹名称都是go, 我们解压到以下目录:

源代码: ~/git_go/go_src
二进制: ~/git_go/go_bin

编译go之前需要设置环境变量,
GOROOT_BOOTSTRAP是go二进制文件夹的所在目录,
GO_GCFLAGS是编译go时使用的参数.

export GOROOT_BOOTSTRAP=~/git_go/go_bin
export GO_GCFLAGS="-N -l"

这里的-N参数代表禁止优化, -l参数代表禁止内联, go在编译目标程序的时候会嵌入运行时(runtime)的二进制,
禁止优化和内联可以让运行时(runtime)中的函数变得更容易调试.

都准备好以后就可以进入go的源代码文件夹执行all.bash编译了:

编译的结果在~/git_go/go_src/bin下:

调试golang源代码

之前CoreCLR的系列中我使用了lldb, 在这个系列中我继续沿用这个调试器.
这个系列中使用的是lldb 4.0.

以以下源代码(hello.go)为例:

package mainimport ("fmt""time"
)func printNumber(from, to int, c chan int) {for x := from; x <= to; x++ {fmt.Printf("%d\n", x)time.Sleep(1 * time.Millisecond)}c <- 0
}func main() {c := make(chan int, 3)go printNumber(1, 3, c)go printNumber(4, 6, c)_, _ = <- c, <- c
}

编译源代码使用以下命令, 这里的-l参数的意思和上面一样, 如果有需要还可以加-N参数:

~/git_go/go_src/bin/go build -gcflags "-l" hello.go

编译后使用lldb运行:

lldb ./hello

go里面的函数符号名称的命名规则是包名称.函数名称, 例如主函数的符号名称是main.main, 运行时中的newobject的符号名称是runtime.newobject.
首先给主函数下一个断点然后运行:

可以看到成功的进入了主函数, 并且有源代码提示.
接下来给按文件名和行数来下断点:

然后查看函数的汇编代码:

关于lldb的命令可以查看这篇文档.
在我使用的环境中lldb可以正常的下断点, 步进和步过go代码或者汇编指令,
打印变量输出的值有可能是错的, 即使不开启优化.

虽然打印变量这个功能不好用, 我们仍然可以直接让go输出我们想要的值,
例如修改runtime/malloc.go输出当前环境下arena|spans|bitmap区的大小:

修改后进入src并执行./make.bash, 然后重新编译目标程序, 运行:

可以看到当前环境下arena是512G, spans是512M, bitmap是16G.
这个方法虽然比较笨, 但是可以在任何情况下输出我们想要的值.

此外, go运行时(runtime)的源代码会包括在目标文件中,
例如你对runtime.newobject下断点可以对go自身的源代码进行调试.

参考链接

https://golang.org
https://golang.org/doc/install/source
https://golang.org/doc/gdb
http://lldb.llvm.org/tutorial.html
http://legendtkl.com/archives

接下来我将分析golang的任务调度机制和三色GC的具体实现, 敬请期待.

Golang源码探索(一) 编译和调试源码相关推荐

  1. zeppelin源码分析(1)——编译、调试和maven modules分析

    Zeppelin,于2016-5-18日从Apache孵化器项目毕业成为Apache顶级项目,采用Java(主要)+Scala+R+PythonR+Bash+JS混合开发,采用maven作为build ...

  2. 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

    作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...

  3. WebRTC源码下载与编译

    WebRTC源码编译 1 几种源码下载方案对比 1.1 拉别人下好的代码 1.2云服务器 1.3 国内镜像 1.4 挂代理(推荐) 2 源码编译环境准备 2.1 环境要求 2.2 代理服务器配置 2. ...

  4. uboot源码下载以及编译

    环境:ubuntu 20.04 uboot源码下载以及编译 1 uboot源码下载: 1.1 进入uboot官网 1.2 下载源码 2 编译uboot 2.1 配置 2.2 编译 2.2.1 确认编译 ...

  5. openfire服务器源码,Openfire源码部署以及编译运行.doc

    Openfire源码部署以及编译运行 Openfire源码下载 可以去官方网站:官网地址/projects/openfire/. 也可以利用eclispe自带的SVN插件导入,再次就过多介绍,官网上写 ...

  6. CoreCLR源码探索(五) GC内存收集器的内部实现 调试篇

    在上一篇中我分析了CoreCLR中GC的内部处理, 在这一篇我将使用LLDB实际跟踪CoreCLR中GC,关于如何使用LLDB调试CoreCLR的介绍可以看: 微软官方的文档,地址 我在第3篇中的介绍 ...

  7. OpenCPN + Ubuntu 18.04 源码编译 + Codeblocks 调试 + wxFormBuilder 安装

    OpenCPN + Ubuntu 18.04 源码编译 文章目录 一.参考资料 二.源码编译流程 三.利用 IDE 编译 四.利用 IDE 调试 四.测试界面开发工具 一.参考资料 OpenCPN - ...

  8. ubuntu编译并调试OpenJDK8源码实践

    最近打算研究一下 jvm 相关的知识,所以想编译 OpenJDK 的源码,一直在Mac上面编译,但是总是出现莫名其妙的error,还找不到有效的解决方式,所以还是进入 Ubuntu 下面进行编译,虽然 ...

  9. 探索比特币源码0-bitcoin的编译

    探索比特币源码0-bitcoin的编译 前言 区块链领域作为一个新兴的热点,迭代的实在是太快了,刚刚入门,必须要抓紧追赶. 在阅读了一些优秀的文档之后,已经对比特币及其背后的实现技术--区块链有了一定 ...

最新文章

  1. OpenCV 相机校正过程中,calibrateCamera函数projectPoints函数的重投影误差的分析
  2. 使用VisualStudio2010连接CodePlex进行代码管理
  3. 实践 Network Policy - 每天5分钟玩转 Docker 容器技术(172)
  4. Delphi 与 DirectX 之 DelphiX(95): TDIB.x
  5. IDEA配置自定义maven库
  6. Java开发:什么是序列化?
  7. MyBatis延迟加载和缓存(4)
  8. 第一章 1 常用库之time
  9. python pip安装pyinstaller报错_pip install pyinstaller (安装过程报错解决)
  10. 宝塔 windows 2012 配置 ftp 允许 fileZilla 连接
  11. 机器学习回归算法—岭回归及案例分析
  12. java uuid 第三方_JAVA生成短8位UUID
  13. 高校水电费管理系统C语言课程设计
  14. Google Play 应用迁移
  15. 阿里云图片如何获取缩略图
  16. python进程已结束,退出代码 -1073740791 (0xC0000409)解决办法
  17. 世间谤我、欺我、辱我、笑我,为之奈何?
  18. RAID技术全解图解-RAID0、RAID1、RAID5、RAID100【转】
  19. 高考放榜季 | 知道创宇全方位保障教育政务网站安全可用
  20. 蒙特卡洛算法及简单应用

热门文章

  1. boost::gregorian模块实现查找给定月份最后一天的测试程序
  2. boost::coroutine2模块实现layout的测试程序
  3. DCMTK:OFnumeric_limits的单元测试
  4. VTK:相互作用之MouseEventsObserver
  5. QT通过JavaScript动态创建QML对象
  6. Qt Creator粘贴和获取代码段
  7. Qt Creator配置项目
  8. OpenGL 投光物Light casters
  9. C语言分区排序partition sort 算法(附完整源码)
  10. 「Python」在虚拟环境中使用pip