引导启动和初始化

  1. 引导启动

1.1启动函数入口

1.1.1 准备运行文件

hello.go

func main() {

    fmt.Println(\"hello world\")

}

使用-gcflags \"-N -l\" 参数关闭编译器代码优化和函数内联,避免断点和单步执行无法准确对应源码行数,避免小函数和局部变量被优化掉。

 

go build -gcflags \"-N -l\" -o hello hello.go

1.1.2 找到入口文件

用GDB 设置断点命令看看这个 rt0_go入门文件在什么位置。

根据系统平台架构不相同,入口文件也会不一样,这里的入口文件在/usr/local/go/src/runtime/rt0_linux_amd64.s第八行。

 

gdb hello

(gdb) info files

Local exec file:

Entry point: 0x4561d0

 

(gdb) b *0x4561d0

Breakpoint 1 at 0x4561d0: file /usr/local/go/src/runtime/rt0_linux_amd64.s, line 8.

1.1.3 查看入口源码

TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8

         …省略代码…

         MOVQ      $main(SB), AX //跳转到62行

 

TEXT main(SB),NOSPLIT,$-8

         MOVQ $runtime·rt0_go(SB), AX

         JMP AX

 

注意:源码文件中的 “·” 符号编译后变成正常的 “.”。

(gdb) b runtime.rt0_go

Breakpoint 2 at 0x44a780: file /usr/local/go/src/runtime/asm_amd64.s, line 12.

TEXT runtime·rt0_go(SB),NOSPLIT,$0

         …省略代码…

         // 初始化函数

         CALL runtime·args(SB)

         CALL runtime·osinit(SB)

         CALL runtime·schedinit(SB)

         // 准备执行runtime.main

         MOVQ $runtime·mainPC(SB), AX

        //创建main goroutine

         CALL runtime·newproc(SB)

         // 让当前线程开始执行main goroutine

         CALL runtime·mstart(SB)

         RET

         DATA runtime·mainPC+0(SB)/8,$runtime·main(SB)

         GLOBL runtime·mainPC(SB),RODATA,$8

 

1.2 初始化流程

schedinit函数

所有运用时环境初始化构造都在里被调,内存分配,垃圾回收,调度器等。

func schedinit() {

//最大系统线程数量设置

sched.maxmcount = 10000

//栈空间复用链表初始化

stackinit()

//内存分配器初始化

mallocinit()

//初始化当前M

mcommoninit(_g_.m)

//垃圾回收初始化

gcinit()

//初始化,调整P的数量

if procresize(int32(procs)) != nil {

throw(\"unknown runnable goroutine during bootstrap\")

}

}

 

初始化操作到此并未结束,因为接下来要执行的是 runtime.main,而不是用户逻

辑入口函数 main.main。

func main() {

//系统后台监控(内存释放,并发调度,垃圾回收监控)

         systemstack(func() {

                   newm(sysmon, nil)

         })

//执行runtime包所有的init函数

runtime_init()

//启动垃圾回收器(后台运行)

gcenable()

//执行用户用户包init(包括标准库)

main_init()

//执行用户逻辑入口,main.main函数

main_main()

//执行结束

exit(0)

}

收藏 打印