有人写的不错了,其实没难的,可能就是第一次不会使用。
总体就是先build,然后再操作了,windows我一般用的是dlv。具体进入gdb后help看下命令帮助即可。
http://lday.me/2017/02/27/0005_gdb-vs-dlv/
顺带简单分析下proc吧。
test.go
func counting(c chan<- int) { for i := 0; i < 10; i++ { time.Sleep(2 * time.Second) c <- i } close(c) } func main() { msg := "Starting main" fmt.Println(msg) bus := make(chan int) msg = "starting a gofunc" go counting(bus) for count := range bus { fmt.Println("count:", count) } }
先编译一下
go build -gcflags “-N -l” test.go
再用dlv
dlv exec test.ext
打个breakpoint
b runtime.init
Breakpoint 1 set at 0x42ed4a for runtime.main() D:/program/Go/src/runtime/proc.go:113
我们即可跳转到proc.go
// The main goroutine. func main() { g := getg() // Racectx of m0->g0 is used only as the parent of the main goroutine. // It must not be used for anything else. g.m.g0.racectx = 0 // Max stack size is 1 GB on 64-bit, 250 MB on 32-bit. // Using decimal instead of binary GB and MB because // they look nicer in the stack overflow failure message. if sys.PtrSize == 8 { maxstacksize = 1000000000 } else { maxstacksize = 250000000 } ... }
对于目前的1.4,我们发现在开启后台系统监控也就是sysmon这边多了对于GOOS编译的识别,主要是对于WebAssembly的支持。
if GOARCH != "wasm" { // no threads on wasm yet, so no sysmon systemstack(func() { newm(sysmon, nil) }) }
这边就是进入执行我们的业务逻辑代码了
fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime fn()
总之分析还是看起来不复杂的,只是一小部分。可认真学习雨痕大神的go学习笔记。