閱讀go語言原始碼1

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前面大概說過bison與yacc的文法,那麼其實go也是用bison來實現的,下面來說說怎麼閱讀go語言原始碼。要看代碼首先得找到代碼的入口,怎麼找呢?你可能首先想到grep main是的,一般來說這是一個沒有爭議的辦法,但是對於go語言來說,這個辦法對,也不對。怎麼說呢?我們用gdb來進行debug就會看到所有的go語言程式的入口居然都在src/lib9/main.c裡的main函數。

#include #define NOPLAN9DEFINES#include extern void p9main(int, char**);intmain(int argc, char **argv){    p9main(argc, argv);    exits("main");    return 99; }

從go/include/libc.h中裡我們可以看到這麼一句

#ifndef NOPLAN9DEFINES#define main    p9main#endif

也就是說,在go語言原始碼裡main函數都重新命名了,所有的函數入口都變成了src/lib9/mina.c,也實際的入口各自的代碼裡,因此說入口是各自的main這句話,對也不對。

那麼先大概說一下go語言的代碼結構

.|-- bin//我自己定義的安裝目錄|-- doc//相關文檔,godoc就是利用這個目錄|   |-- codelab|   |   `-- wiki|   |-- codewalk|   |-- devel|   |-- gopher|   |-- progs|   `-- talks|       `-- io2010|-- include//一些全域的定義檔案|-- lib//一些lib9相關的全域庫|   |-- codereview|   `-- godoc|-- misc//一些工具|   |-- arm|   |-- bash|   |-- bbedit|   |-- cgo|   |   |-- gmp|   |   |-- life|   |   `-- stdio|   |-- dashboard|   |   `-- godashboard|   |-- emacs|   |-- kate|   |-- nacl|   |-- vim|   |   |-- ftdetect|   |   `-- syntax|   `-- xcode|-- pkg//編譯好的go庫|   `-- linux_amd64|       |-- archive|       |-- compress|       |-- container|       |-- crypto|       |-- debug|       |-- encoding|       |-- exp|       |-- go|       |-- hash|       |-- http|       |-- image|       |-- io|       |-- os|       |-- rpc|       |-- runtime|       `-- testing|-- src|   |-- cmd//go語言相關的程式|   |   |-- 5a|   |   |-- 5c|   |   |-- 5g|   |   |-- 5l|   |   |-- 6a//amd64的彙編器|   |   |-- 6c//amd64的c編譯器|   |   |-- 6g//amd64的編譯器|   |   |-- 6l//amd64的連結器|   |   |-- 8a|   |   |-- 8c|   |   |-- 8g|   |   |-- 8l|   |   |-- cc|   |   |-- cgo|   |   |-- cov|   |   |-- ebnflint|   |   |-- gc|   |   |-- godefs|   |   |-- godoc|   |   |-- gofmt|   |   |-- goinstall|   |   |-- gopack|   |   |-- gotest|   |   |-- goyacc|   |   |-- hgpatch|   |   |-- ld|   |   |-- nm|   |   `-- prof|   |-- lib9//lib9相關的庫|   |   |-- fmt|   |   `-- utf|   |-- libbio//全域庫|   |-- libcgo//cgo的庫|   |-- libmach//庫|   `-- pkg//go庫|       |-- archive|       |-- asn1|       |-- big|       |-- bufio|       |-- bytes|       |-- cmath|       |-- compress|       |-- container|       |-- crypto|       |-- debug|       |-- ebnf|       |-- encoding|       |-- exec|       |-- exp|       |-- expvar|       |-- flag|       |-- fmt|       |-- go|       |-- gob|       |-- hash|       |-- html|       |-- http|       |-- image|       |-- io|       |-- json|       |-- log|       |-- math|       |-- mime|       |-- net|       |-- netchan|       |-- nntp|       |-- once|       |-- os|       |-- patch|       |-- path|       |-- rand|       |-- reflect|       |-- regexp|       |-- rpc|       |-- runtime|       |-- scanner|       |-- sort|       |-- strconv|       |-- strings|       |-- sync|       |-- syscall|       |-- syslog|       |-- tabwriter|       |-- template|       |-- testing|       |-- time|       |-- unicode|       |-- unsafe|       |-- utf16|       |-- utf8|       |-- websocket|       `-- xml`-- test//測試    |-- bench    |-- bugs    |-- chan    |-- fixedbugs    |   |-- bug083.dir    |   |-- bug088.dir    |   |-- bug106.dir    |   |-- bug133.dir    |   |-- bug160.dir    |   |-- bug191.dir    |   |-- bug222.dir    |   |-- bug226.dir    |   |-- bug248.dir    |   `-- bug282.dir    |-- garbage    |-- interface    |-- ken    |-- nilptr    `-- syntax

我們先來看一個go語言的hello world檔案hello.go

package mainfunc main(){    println("Hello World");}

那麼這個檔案要被編譯連結成一個可執行檔,那麼要執行如下命令:

6g hello.o6l hello.6 -o hello

很顯然最關鍵的就是6g和6l兩個程式,那麼我們就從6g開始

首先gdb -tui開啟tui介面的gdb程式

然後輸入file 6g載入6g程式,就可以看到

/home/hoping/go/src/lib9/main.c,然後輸入start後,step進入了/home/hoping/go/src/cmd/gc/lex.c的main函數

因此我們只需要看這個檔案就大概可以看到程式的執行流程了。接下來暫時不需要gdb了,我們換vi和ctags。

在go目錄執行ctags -R *來產生tag,然後用vi開啟lex.c進入main函數,其實即使你看了這個函數也不會有太多收穫。

正如我們前面說過的那樣,6g是用bison的,那麼顯然我們需要找到bison檔案和yylex函數即可。既然入口在gc檔案夾,那麼猜想y檔案也在gc檔案夾,於是進入ls *.y之後可以看到go.y。而go.y的輸入全是由yylex函數來提供的。所以首先我們來看看yylex函數,在go檔案夾下執行vim -t yylex,然後選擇gc檔案夾那個。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.