GO:源碼的修改、調試

GO:源碼的修改、調試

需求:

1.通過修改GO源碼邏輯,實現想要的自定義功能。

例如:修改GO的net/http等相關包的代碼,內嵌針對HTTP請求/應答的原始消息輸出到日誌,方便定位排查。

2.臨時修改GO源碼邏輯,進行復雜的調試,便於理解GO代碼。

例如:學習GO的net/http包,看着一長串的調用【深度、廣度】,如果能調試輸出,是否更便於理解代碼呢?

實現:

直接修改GO源碼,編譯。

例子:

我的開發環境:

[test1280@localhost ~]$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/test1280/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/test1280/gopath"
GOPROXY="https://goproxy.io"
GORACE=""
GOROOT="/home/test1280/go"
GOTMPDIR=""
GOTOOLDIR="/home/test1280/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build447053725=/tmp/go-build -gno-record-gcc-switches"

我的目錄結構:

[test1280@localhost ~]$ tree -L 1
.
├── go
├── go1.12.5.linux-amd64.tar.gz
├── gopath
└── myproject

3 directories, 1 file
[test1280@localhost ~]$ tree -L 2
.
├── go
│   ├── api
│   ├── AUTHORS
│   ├── bin
│   ├── CONTRIBUTING.md
│   ├── CONTRIBUTORS
│   ├── doc
│   ├── favicon.ico
│   ├── lib
│   ├── LICENSE
│   ├── misc
│   ├── PATENTS
│   ├── pkg
│   ├── README.md
│   ├── robots.txt
│   ├── src
│   ├── test
│   └── VERSION
├── go1.12.5.linux-amd64.tar.gz
├── gopath
└── myproject
    ├── go.mod
    ├── main.go
    └── myproject

11 directories, 13 files

我的測試代碼:

[test1280@localhost myproject]$ cat go.mod 
module myproject

go 1.12
[test1280@localhost myproject]$ cat main.go
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	resp, err := http.Get("http://127.0.0.1:8080/")
	if err != nil {
		fmt.Println(err)
		return
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(body))
}

正常編譯運行:

[test1280@localhost myproject]$ go build && ./myproject
{
	"current":	"Sat Aug 17 02:56:09 2019"
}

想要達到的效果:調用http.Get時,記錄一條日誌到標準輸出。

修改GO源碼:

我的GO源碼位置從上面的信息中可知是在“$HOME/go/src”,修改net/http/client.go中的Get函數:

func Get(url string) (resp *Response, err error) {
        fmt.Println("test1280: call http.Get()")
        return DefaultClient.Get(url)
}

備註:由於client.go中已import “fmt”,因此我添加的fmt.Println【內嵌的自定義邏輯】不需要再額外引入。

重新編譯GO項目:

[test1280@localhost myproject]$ go build && ./myproject 
test1280: call http.Get()
{
	"current":	"Sat Aug 17 03:04:02 2019"
}

  • 修改的是$HOME/go/src中的GO源碼;
  • 重新編譯的是GO應用(GO工具鏈發現GO源碼有被修改,重新編譯GO源碼以及GO應用);
  • 輸出將顯示在stdout、stderr;(默認情況下,例如重定向輸出例外)

如果你想要調試GO源碼,可像我一樣增加fmt.Print輸出信息,這樣你重新編譯GO程序,調試將顯示在終端。

如果你想要改變GO源碼,例如記錄HTTP請求/應答原始的報文,可將其內嵌到net/http等包中,記錄到日誌。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章