关注爱因诗贤
每天进步一点点
导读
随着技术的发展,大多的PHPer都开始转型golang。这个也是golang因为go的一些特别深受大家喜爱。我们团队也在试水,在内部的一些小项目上做了试探。在此同时我作为试探的一员身先士卒,沙场练兵。从中也琢磨到一些技巧希望能和大家一起学习共勉。
一、前期准备:
go版本:go1.13.4
由于是做源码分析调试,我们必须找到适合自己的工具。咱们调试的话可以考虑几种工具
1)gdb linux使用比较合适
2)lldb mac自带,不过建议dlv
3)dlv go开发的调试工具
本文中主要以dlv为主,接下来我们一起来安装一下dlv。
第一步下载
第二步编译:
$GOPATH 是golang的环境变量,我使用的是Linux,建议大家在/etc/profile设置,mac相同。
windows设置gopath
https://jingyan.baidu.com/article/5d368d1eb616133f60c057bf.html
第三步设置环境变量:
/data/gopath/bin 为你自己的go的bin目录
初始化环境变量
dlv参数介绍(常用)
命令(全)命令(简写)备注restartr重新启动程序continuec运行到断点或者程序终止breakb设置断点breakpointsbp打印设置断点nextn执行下一行listl查看当前代码steps进入下一层stackbt当前调用栈printp打印变量
二.调试:
1.编译调试文件
代码内容
编译
必须这样编译,待能用dlv打印导出变量信息;
2.载入文件
设置rt0_go断点,程序入口
是不是很好奇为什么入口在runtime.rt0_go
可以打开程序后输入r,在输入list,然后在输入si;si是单步cpu指令;
其实go在运行时会根据系统和CPU的不同,找到底层代码下的,rt0_**.s的汇编代码,汇编代码中再去调转到runtime.rt0_go 。
当然由于系统的不同可执行程序的形式不同。
常见的可执行程序可以分为三大类:
1)PE文件
PE文件主要是Windows系列系统,可执行文件索引;
2)ELF文件
ELF文件是linux系列系统,可执行文件索引;
3)mach-o文件
mach-o是mac系列系统的可执行文件格式,苹果系统是基于FreeBSD的,属于unix-like操作系统;
有一篇比较不错的文章可以推荐给大家:
https://blog.csdn.net/abc_12366/article/details/88205670
好的我们继续往下说,我们进入
我们按住n执行停留到212行
我们可以看到runtime.args 、runtime.osinit和runtime.schedinit三个函数调用。我们可以依次输入si进入函数体内查看
args函数主要用途整理命令行参数;
osint函数是确定CPU Core数量
schedinit源码如下:
schedinit主要作用是所有运行时环境初始化;我们继续下一个断点,然后往下执行:
runtime/proc.go部分源码
我们执行到fn()出可以按s
这样就来到了我们程序的代码;这时我们可以看一下我们的调度栈
执行完成程序完成之后又回到runtime/proc.go中if atomic.Load(&runningPanicDefers) 处
继续往下执行,一直到exit(0)处,按si执行。
程序回到sys_linux_amd64.s汇编代码中的runtime.exit
最终程序结束;
三.调用流程:
非goroutine退出情况
本文使用 文章同步助手 同步