Golang原始碼探索 一 編譯和除錯原始碼

2022-03-04 05:33:49 字數 2978 閱讀 4911

go可以說是近幾年最熱門的新興語言之一了, 一般人看到分布式大資料就會想到go,

這個系列的文章會通過研究golang的源**來分析內部的實現原理,

和coreclr不同的是, golang的源**已經被很多人研究過了, 我將會著重研究他們未提到過的部分.

另一點和coreclr不同的是, golang的源**非常易懂, 注釋也非常的豐富,

很明顯google的工程師在寫**的時候有考慮其他人會去看這份**.

儘管**非常易懂, 研究它們還是需要實際執行和除錯才能得到更好的理解,

這個系列分析的golang源**是google官方的實現的1.9.2版本, 不適用於其他版本和gccgo等其他實現,

執行環境是ubuntu 16.04 lts 64bit.

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下:

之前coreclr的系列中我使用了lldb, 在這個系列中我繼續沿用這個偵錯程式.

這個系列中使用的是lldb 4.0.

以以下源**(hello.go)為例:

package main

import (

"fmt"

"time"

)func printnumber(from, to int, c chan int)

c }func main()

編譯源**使用以下命令, 這裡的-l引數的意思和上面一樣, 如果有需要還可以加-n引數:

~/git_go/go_src/bin/go build -gcflags "-l" hello.go
編譯後使用lldb執行:

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自身的源**進行除錯.

/doc/install/source

/doc/gdb

接下來我將分析golang的任務排程機制和三色gc的具體實現, 敬請期待.

react原始碼探索

react核心部分為 1 虛擬dom物件 reactdom.render args,element 這個方法第乙個引數接收三種形式的內容的 第一種 字串 第二種 由createclass建立的物件,使用createelement處理 第三種 直接有createelement建立的物件 這些還未呼叫r...

MyBatis原始碼探索

每個基於 mybatis 的應用都是以乙個 sqlsessionfactory 的例項為中心的。sqlsessionfactory 的例項可以通過 sqlsessionfactorybuilder 獲得。而 sqlsessionfactorybuilder 則可以從 xml mybatis conf...

Byte的原始碼探索

非可變類 final class 實現對比介面 comparable 繼承於數字類 numberbyte min value 最小值 byte max value 最大值 classtype 類型別 byte value 初始值 int size bit位數 int bytes 位元組數static...