Closed limpo1989 closed 1 year ago
执行热修复之后调用符合期望,但是多次(我这里测试大概2000次调用)进行调用就会开始报异常 下面是我的测试代码,在执行代码之前就进行修复(确保不存在多线程补丁问题)
main.go
package main import ( "fmt" "io" "net/http" "os" "time" hotfix "github.com/lsg2020/go-hotfix" "gocase/gofix/route" ) var HotfixVersion = "main" func main() { http.HandleFunc("/", route.Index) // 热修复 route.Index 逻辑 { fmt.Println("start patching...") msg, err := hotfix.Hotfix("http_v1.so", []string{"gocase/gofix/route.Index"}, []bool{false}, true) if nil != err { panic(fmt.Errorf("%w: %s", err, msg)) } fmt.Println("start patching... finished", msg) } // 等3s后开始启动客户端访问接口 time.AfterFunc(time.Second*3, func() { fmt.Println("start client...") for i := 0; i < 3; i++ { go startClient() } }) // 启动http服务器 fmt.Println("http server listen...") err := http.ListenAndServe(":8080", nil) fmt.Println("http server listen failed: ", err) } func startClient() { for { resp, err := http.Get("http://127.0.0.1:8080/") if nil != err { fmt.Println("http.Get: ", err) return } io.Copy(os.Stdout, resp.Body) resp.Body.Close() } }
route/index.go
package route import ( "fmt" "net/http" "sync/atomic" ) var counter int32 func Index(writer http.ResponseWriter, request *http.Request) { // 编译插件之前切换下列两行注释,模拟插件逻辑更新 fmt.Fprintln(writer, "main: hello go-hotfix/", atomic.AddInt32(&counter, 1)) //fmt.Fprintln(writer, "plugin: hello go-hotfix/", atomic.AddInt32(&counter, 1)) }
run_http.sh
#!/bin/bash set -e echo "build main program..." go build -gcflags=all=-l -ldflags="-X main.HotfixVersion=main" -o http_main main.go echo "please modify v1 plugin, press enter key to continue..." read input echo "build plugin v1..." go build -gcflags=all=-l -buildmode=plugin -ldflags="-X main.HotfixVersion=v1" -o http_v1.so main.go echo "run main program..." ./http_main
输出结果
plugin: hello go-hotfix/ 2149 plugin: hello go-hotfix/ 2150 plugin: hello go-hotfix/ 2151 plugin: hello go-hotfix/ 2152 plugin: hello go-hotfix/ 2153 plugin: hello go-hotfix/ 2154 plugin: hello go-hotfix/ 2155 plugin: hello go-hotfix/ 2157 plugin: hello go-hotfix/ 2156 plugin: hello go-hotfix/ 2158 2023/05/15 18:06:43 http: panic serving 127.0.0.1:55544: runtime error: invalid memory address or nil pointer dereference goroutine 2903 [running]: net/http.(*conn).serve.func1() /usr/local/go/src/net/http/server.go:1854 +0xbf panic({0xb5c0c0, 0xf2cca0}) /usr/local/go/src/runtime/panic.go:890 +0x262 net/http.HandlerFunc.ServeHTTP(0x778085?, {0xc5c190?, 0xc0001301c0?}, 0xc515d0?) /usr/local/go/src/net/http/server.go:2123 +0x2f net/http.(*ServeMux).ServeHTTP(0x0?, {0xc5c190, 0xc0001301c0}, 0xc000132400) /usr/local/go/src/net/http/server.go:2500 +0xc2 net/http.serverHandler.ServeHTTP({0xc0057e2810?}, {0xc5c190?, 0xc0001301c0?}, 0xc000132400?) /usr/local/go/src/net/http/server.go:2936 +0x23c net/http.(*conn).serve(0xc00043a480, {0xc5c7e8, 0xc002320a50}) /usr/local/go/src/net/http/server.go:1995 +0xad0 created by net/http.(*Server).Serve /usr/local/go/src/net/http/server.go:3089 +0x45f ...
根据测试可以确定问题是 gomonkey 导致的 agiledragon/gomonkey/#132
执行热修复之后调用符合期望,但是多次(我这里测试大概2000次调用)进行调用就会开始报异常
下面是我的测试代码,在执行代码之前就进行修复(确保不存在多线程补丁问题)
main.go
route/index.go
run_http.sh
输出结果