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等包中,记录到日志。

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