-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Go程序的初始化工作 #7
Comments
首先需要找到整个程序的entry point,然后再梳理对应的流程。 entry point查看程序的
1、使用 a. 编译源码: b. 使用 # readelf -h main
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x44e3b0
Start of program headers: 64 (bytes into file)
Start of section headers: 456 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 7
Size of section headers: 64 (bytes)
Number of section headers: 21
Section header string table index: 6 其中, 使用 ./main: file format elf64-x86-64
Disassembly of section .text:
000000000044e3b0 <_rt0_amd64_linux>:
// license that can be found in the LICENSE file.
#include "textflag.h"
TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
LEAQ 8(SP), SI // argv
44e3b0: 48 8d 74 24 08 lea 0x8(%rsp),%rsi
MOVQ 0(SP), DI // argc
44e3b5: 48 8b 3c 24 mov (%rsp),%rdi
MOVQ $main(SB), AX
44e3b9: 48 8d 05 10 00 00 00 lea 0x10(%rip),%rax # 44e3d0 <main>
JMP AX
44e3c0: ff e0 jmpq *%rax
... 2、使用 或者使用 # dlv debug main.go
Type 'help' for list of commands.
(dlv) l
> _rt0_amd64_linux() /usr/local/go/src/runtime/rt0_linux_amd64.s:8 (PC: 0x465660)
Warning: debugging optimized function
3: // license that can be found in the LICENSE file.
4:
5: #include "textflag.h"
6:
7: TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
=> 8: JMP _rt0_amd64(SB)
9:
10: TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0
11: JMP _rt0_amd64_lib(SB) |
_rt0_amd64_linux入口_rt0_amd64_linux位于
首先,把
初始化g0跳转到
初始化完后,g0与内存栈的状态如下: |
初始化g0跳转到
初始化完后,g0与内存栈的状态如下: |
cgo初始化g0初始化完成后,接着探测CPU信息、CPU类型、指令集等,接着做cgo相关的初始化,该部分详细的分析暂时忽略,不影响分析初始化流程。
接着做cgo初始化,
|
初始化TLS初始化tls,线程局部存储 Thread-local storage是为每一个线程提供各自的存储。 TLS的对象是跟着线程开始时分配,线程结束后回收,每个线程有各自的独占实例对象。简单说就是各个线程自己的局部变量。
说明:
上述过程即完成了TLS的初始化工作。 |
绑定m0和g0初始化TLS后,就开始绑定m0和g0。
绑定m0和g0后,g0和m0、寄存器、内存之间的关系更新如下图, 完成g0和m0的初始化操作后,就进入实际的main函数启动。
|
总结程序在启动的时候,第一个指令地址存放在 初始化过程中,会对2个特殊的对象进行初始化:
接着就进入了程序启动的流程,对应的流程总结为下列步骤,
|
Go程序的初始化工作
对于用户程序来说,main package中的main()是程序的入口函数。
于是,有了如下问题:
The text was updated successfully, but these errors were encountered: