huandu / go-tls

A bit safer approach to implement Thread Local Storage (TLS) for Go 1.7+.
MIT License
162 stars 15 forks source link

tls.Unload error in goroutine exit #9

Closed ychellboy closed 3 years ago

ychellboy commented 3 years ago

code as fallow:

func CreateGls() {
    zaplog.LoggerSugar.Debugf("GLS create goid:%d", GoID())
    TLS.AtExit(func() {
        zaplog.LoggerSugar.Debugf("GLS delete goid:%d", GoID())
        TLS.Unload()
    })
}

testcase:

func TestAutoReleaseWhenGoExit(t *testing.T) {
    go func() {
        CreateGls()
        time.Sleep(10*time.Second)
    }()

    zaplog.LoggerSugar.Debugf("main goroutine goid:%d", GoID())
    time.Sleep(20*time.Second)
    zaplog.LoggerSugar.Debugf("main goroutine exit")
}

error occurs like this:

=== RUN TestAutoReleaseWhenGoExit 2020-10-20T17:39:25.252+0800 DEBUG gls/gls_test.go:15 main goroutine goid:1 2020-10-20T17:39:25.252+0800 DEBUG gls/gls.go:17 GLS create goid:2 2020-10-20T17:39:35.255+0800 DEBUG gls/gls.go:19 GLS delete goid:2 panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x12baa6a]

goroutine 6 [running]: server/internal/common/gls/internal/tls.resetAtExit() /Users/yc/workspace/goproject/uuu/antia-server/internal/common/gls/internal/tls/tls.go:175 +0x17a server/internal/common/gls/internal/tls.hackedGoexit1() /Users/yc/workspace/goproject/uuu/antia-server/internal/common/gls/internal/tls/goexit.go:72 +0x22 created by server/internal/common/gls.TestAutoReleaseWhenGoExit /Users/yc/workspace/goproject/uuu/antia-server/internal/common/gls/gls_test.go:10 +0x39

Process finished with exit code 1

huandu commented 3 years ago

It's not valid to call Unload in AtExit handler. There is no need to do this. All resource will be unloaded automatically after goroutine exiting.

I can update a version to prevent panic in this case later.