We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
使用gomonkey配合plugin,实现一个简单的热修复功能会发生崩溃,刚开始patching之后一切正常,运行一会以后就会发生错误
main.go
package main import ( "fmt" "io" "net/http" "os" "plugin" "reflect" "sync/atomic" "time" gomonkey "github.com/agiledragon/gomonkey/v2" "gocase/gopatch/route" ) var HotfixVersion = "main" func IndexHandler() func(http.ResponseWriter, *http.Request) { //return route.Index var counter int32 return func(writer http.ResponseWriter, request *http.Request) { fmt.Fprintln(writer, "plugin handle:", atomic.AddInt32(&counter, 1)) } } func main() { http.HandleFunc("/", route.Index) // 热修复 route.Index 逻辑 { p, err := plugin.Open("http_v1.so") if nil != err { panic(err) } sym, err := p.Lookup("IndexHandler") if nil != err { panic(err) } fn := sym.(func() func(http.ResponseWriter, *http.Request)) handler := fn() fmt.Println("patching...", reflect.ValueOf(route.Index).Pointer(), " => ", reflect.ValueOf(handler).Pointer()) gomonkey.ApplyFunc(route.Index, handler) } // 等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.go
var counter int32 func Index(writer http.ResponseWriter, request *http.Request) { fmt.Fprintln(writer, "main: hello gopatch/", 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
输出结果
patching... 8606880 => 139904623738208 http server listen... start client... plugin handle: 1 plugin handle: 3 plugin handle: 2 plugin handle: 4 plugin handle: 5 plugin handle: 6 plugin handle: 7 plugin handle: 9 plugin handle: 8 plugin handle: 10 plugin handle: 11 plugin handle: 13 plugin handle: 12 plugin handle: 14 plugin handle: 15 plugin handle: 16 plugin handle: 17 plugin handle: 18 plugin handle: 19 plugin handle: 20 plugin handle: 21 plugin handle: 22 plugin handle: 23 plugin handle: 25 plugin handle: 24 plugin handle: 26 plugin handle: 27 plugin handle: 29 plugin handle: 28 plugin handle: 31 plugin handle: 32 plugin handle: 33 plugin handle: 30 plugin handle: 34 plugin handle: 35 plugin handle: 36 plugin handle: 38 plugin handle: 37 plugin handle: 39 plugin handle: 41 unexpected fault address 0x8dffe8 fatal error: fault plugin handle: 40 [signal SIGSEGV: segmentation violation code=0x2 addr=0x8dffe8 pc=0x8dffe8] goroutine 179 [running]: runtime.throw({0x8d9d5a?, 0xc000016000?}) /usr/local/go/src/runtime/panic.go:1047 +0x5d fp=0xc000206a70 sp=0xc000206a40 pc=0x58e6dd runtime.sigpanic() /usr/local/go/src/runtime/signal_unix.go:851 +0x1e5 fp=0xc000206aa0 sp=0xc000206a70 pc=0x5a5465 net/http.HandlerFunc.ServeHTTP(0x686a65?, {0x929960?, 0xc000344000?}, 0x922938?) /usr/local/go/src/net/http/server.go:2123 +0x2f fp=0xc000206ac8 sp=0xc000206aa0 pc=0x80444f net/http.(*ServeMux).ServeHTTP(0x0?, {0x929960, 0xc000344000}, 0xc0001ce000) /usr/local/go/src/net/http/server.go:2500 +0xc2 fp=0xc000206b00 sp=0xc000206ac8 pc=0x8059a2 net/http.serverHandler.ServeHTTP({0xc00020b3b0?}, {0x929960?, 0xc000344000?}, 0xc0001ce000?) /usr/local/go/src/net/http/server.go:2936 +0x23c fp=0xc000206b98 sp=0xc000206b00 pc=0x806fdc net/http.(*conn).serve(0xc000208f30, {0x929d68, 0xc00011af00}) /usr/local/go/src/net/http/server.go:1995 +0xad0 fp=0xc000206fb8 sp=0xc000206b98 pc=0x8035b0 net/http.(*Server).Serve.func3() /usr/local/go/src/net/http/server.go:3089 +0x2e fp=0xc000206fe0 sp=0xc000206fb8 pc=0x80792e runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000206fe8 sp=0xc000206fe0 pc=0x5c2861 created by net/http.(*Server).Serve /usr/local/go/src/net/http/server.go:3089 +0x45f ...
The text was updated successfully, but these errors were encountered:
测试环境:
Sorry, something went wrong.
切换为 gohook 后运行正常了,不会崩溃了
No branches or pull requests
使用gomonkey配合plugin,实现一个简单的热修复功能会发生崩溃,刚开始patching之后一切正常,运行一会以后就会发生错误
main.go
route.go
run_http.sh
输出结果
The text was updated successfully, but these errors were encountered: