uber-go / goleak Goto Github PK
View Code? Open in Web Editor NEWGoroutine leak detector
License: MIT License
Goroutine leak detector
License: MIT License
// 1.调用第三方接口由于没有设置超时时间,导致请求阻塞着
func err3() {
httpClient := http.Client{
//Timeout: time.Second * 2, // todo 设置httpClicent的超时时间,否则由于响应慢而一直堵塞
}
for {
go func() {
resp, err := httpClient.Get("https://www.google.com/")
if err != nil {
fmt.Printf("http.Get err: %v\n", err)
} else {
fmt.Println(resp.Status)
}
}()
time.Sleep(time.Second * 1)
fmt.Println("goroutines: ", runtime.NumGoroutine())
}
}
with a gRPC client test, there are so many leaks, is it OK or too early to use goleak ?
Running tool: /usr/local/bin/go test -timeout 30s my_project/test -run ^TestListAddresses$
PASS
goleak: Errors on successful test run: found unexpected goroutines:
[Goroutine 20 in state select, with my_project/vendor/go.opencensus.io/stats/view.(*worker).start on top of the stack:
Goroutine 40 in state select, with my_project/vendor/google.golang.org/grpc.(*addrConn).transportMonitor on top of the stack:
Goroutine 39 in state select, with my_project/vendor/google.golang.org/grpc.(*ccBalancerWrapper).watcher on top of the stack:
Goroutine 27 in state select, with my_project/vendor/google.golang.org/grpc.(*ccResolverWrapper).watcher on top of the stack:
Goroutine 55 in state select, with my_project/vendor/google.golang.org/grpc.(*ccBalancerWrapper).watcher on top of the stack:
Goroutine 28 in state select, with my_project/vendor/google.golang.org/grpc.(*ccResolverWrapper).watcher on top of the stack:
Goroutine 56 in state select, with my_project/vendor/google.golang.org/grpc.(*addrConn).transportMonitor on top of the stack:
Goroutine 45 in state select, with my_project/vendor/google.golang.org/grpc/transport.(*controlBuffer).get on top of the stack:
Goroutine 69 in state select, with my_project/vendor/google.golang.org/grpc/transport.(*controlBuffer).get on top of the stack:
FAIL my_project/test 1.621s
Error: Tests failed.
Problem:
Using goleak with trace flag in earlier versions of go (go1.13.10) is working fine due to fixed issue #39.
But in recent version of go (go1.17.1) testing simple programs with trace flag
is failing again. I think the stack trace has now hidden the call to runtime.goparkunlock
func Test(t *testing.T) {
defer goleak.VerifyNone(t)
}
make test:
[Goroutine 18 in state trace reader (blocked), with runtime.ReadTrace on top of the stack:
goroutine 18 [trace reader (blocked)]:
runtime.ReadTrace()
/usr/local/go/src/runtime/trace.go:412 +0xd2
runtime/trace.Start.func1()
/usr/local/go/src/runtime/trace/trace.go:129 +0x47
created by runtime/trace.Start
/usr/local/go/src/runtime/trace/trace.go:127 +0xf4
Possible Solution:
Removing this piece of code:
Lines 159 to 161 in 1e9de54
We've found an interesting thing during using goleak on our CI, that goleak can detect leaked goroutine from other tests.
goleak_test.go
package goleak_test
import (
"go.uber.org/goleak"
"testing"
"time"
)
func TestA(t *testing.T) {
go func() {
for {
<-time.After(time.Millisecond * 100)
}
}()
}
func TestB(t *testing.T) {
defer goleak.VerifyNone(t)
}
Expected: TestB should pass
Actual: TestB fails with error "found unexpected goroutines:"
The golang.org/x/lint library is marked as deprecated / unmaintained / readonly
This library takes an explicit dependency on it in https://github.com/uber-go/goleak/blob/master/tools_test.go in order to record a specific version of it in go.mod, for use with go install
in the make lint
target.
The same result could be achieved by installing the same version explicitly in make lint
with go install golang.org/x/lint/[email protected]
, and the tools_test.go and go.mod reference could be dropped, to avoid propagating an unmaintained dependency into downstreams that use this library.
It would be amazing to have goleak working on Benchmarks as well. However, I think some functions might needed to be filtered by default. Repro:
func BenchmarkGoroutines(b *testing.B) {
defer goleak.VerifyNone(b)
b.ResetTimer()
for i := 0; i < b.N; i++ {
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
}()
go func() {
defer wg.Done()
}()
wg.Wait()
}
}
Output:
BenchmarkGoroutines
leaks.go:78: found unexpected goroutines:
[Goroutine 1 in state chan receive, with testing.(*B).run1 on top of the stack:
goroutine 1 [chan receive]:
testing.(*B).run1(0xc00016a240)
/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:235 +0xb2
testing.(*B).Run(0xc00016a480, {0x6f69de?, 0x0?}, 0x722460)
/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:676 +0x445
testing.runBenchmarks.func1(0xc00016a480?)
/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:550 +0x6e
testing.(*B).runN(0xc00016a480, 0x1)
/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:193 +0x102
testing.runBenchmarks({0x6ffdf2, 0x28}, 0x945c20?, {0x909c80, 0x2, 0x40?})
/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:559 +0x3f2
testing.(*M).Run(0xc000132f00)
/home/bwplotka/.gvm/gos/go1.18.3/src/testing/testing.go:1726 +0x811
main.main()
_testmain.go:57 +0x1aa
]
--- FAIL: BenchmarkGoroutines
FAIL
Process finished with the exit code 1
Tested on both Go version 1.18.3 and 1.19
We have a couple of strings.Contains
checks , e.g.,
Line 142 in 7380c5a
We should parse the stack trace and filter on specific parts of the trace (E.g., only function name) rather than doing a string comparison against the entire stack trace which contains filesystem paths etc.
rules_go added a SIGTERM handler that adds a leaking goroutine to test cases: bazelbuild/rules_go#3749
goleak will come with a default ignorelist entry in the future as far as I understood @linzhp.
-- bazelbuild/rules_go#3827 (comment)
Can this be added? Adding a manual ignore in every test is not very usable.
time.Tick
[1] is documented as having a leak;
be aware that without a way to shut it down the underlying
Ticker cannot be recovered by the garbage collector; it "leaks"
I expected go.uber.org/goleak
to be able to uncover such a leak but it didn't seem to.
Here's my example program:
main.go
package main
import (
"fmt"
"time"
)
func hello() string {
t := time.Tick(3 * time.Second) //leak
final := time.Tick(10 * time.Second) //another leak
for {
select {
case <-t:
fmt.Println("ticked")
case <-final:
fmt.Println("FINAL ticked")
return "final hello"
default:
fmt.Println("NOT ticked")
time.Sleep(1 * time.Second)
}
}
}
main_test.go
package main
import (
"testing"
"go.uber.org/goleak"
)
func TestHello(t *testing.T) {
defer goleak.VerifyNone(t)
res := hello()
t.Log(res)
}
then I run tests as;
go test -v -race -count=1 ./...
ref:
This is for flexibility and users can adjust to their own scenarios. Or do we have any other concerns?
/assign
Hi, can you clarify a license for this project? Thank you.
The issue came from a quite common scenario, which is to read all bytes from response body after a HTTP method call.
To demonstrate the issue, run the following test code with go test
, which gives found unexpected goroutines
:
package main
import (
"io"
"net/http"
"testing"
"go.uber.org/goleak"
"gotest.tools/v3/assert"
)
func TestLeak(t *testing.T) {
defer goleak.VerifyNone(t)
request, err := http.NewRequest(http.MethodGet, "https://google.com", nil)
assert.NilError(t, err)
client := http.Client{}
response, err := client.Do(request)
assert.NilError(t, err)
defer response.Body.Close()
_, err = io.ReadAll(response.Body)
assert.NilError(t, err)
}
full test output:
$ go test
--- FAIL: TestLeak (1.26s)
main_test.go:28: found unexpected goroutines:
[Goroutine 14 in state IO wait, with internal/poll.runtime_pollWait on top of the stack:
goroutine 14 [IO wait]:
internal/poll.runtime_pollWait(0x7f945c1e0398, 0x72)
/home/wxh/.local/go/src/runtime/netpoll.go:305 +0x89
internal/poll.(*pollDesc).wait(0xc000154280?, 0xc0000ca000?, 0x0)
/home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
/home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).Read(0xc000154280, {0xc0000ca000, 0x2000, 0x2000})
/home/wxh/.local/go/src/internal/poll/fd_unix.go:167 +0x25a
net.(*netFD).Read(0xc000154280, {0xc0000ca000?, 0xc00017edd8?, 0xc0004d5808?})
/home/wxh/.local/go/src/net/fd_posix.go:55 +0x29
net.(*conn).Read(0xc00009c000, {0xc0000ca000?, 0xc0000c68f0?, 0x2c?})
/home/wxh/.local/go/src/net/net.go:183 +0x45
crypto/tls.(*atLeastReader).Read(0xc0002d4138, {0xc0000ca000?, 0x0?, 0x29f6540f238f2947?})
/home/wxh/.local/go/src/crypto/tls/conn.go:787 +0x3d
bytes.(*Buffer).ReadFrom(0xc0000a0278, {0x7c3860, 0xc0002d4138})
/home/wxh/.local/go/src/bytes/buffer.go:202 +0x98
crypto/tls.(*Conn).readFromUntil(0xc0000a0000, {0x7c3b80?, 0xc00009c000}, 0xc0000a41c0?)
/home/wxh/.local/go/src/crypto/tls/conn.go:809 +0xe5
crypto/tls.(*Conn).readRecordOrCCS(0xc0000a0000, 0x0)
/home/wxh/.local/go/src/crypto/tls/conn.go:616 +0x116
crypto/tls.(*Conn).readRecord(...)
/home/wxh/.local/go/src/crypto/tls/conn.go:582
crypto/tls.(*Conn).Read(0xc0000a0000, {0xc0001cf000, 0x1000, 0x11?})
/home/wxh/.local/go/src/crypto/tls/conn.go:1287 +0x16f
bufio.(*Reader).Read(0xc0001af1a0, {0xc0001aad60, 0x9, 0xc0004d5d18?})
/home/wxh/.local/go/src/bufio/bufio.go:237 +0x1bb
io.ReadAtLeast({0x7c3760, 0xc0001af1a0}, {0xc0001aad60, 0x9, 0x9}, 0x9)
/home/wxh/.local/go/src/io/io.go:332 +0x9a
io.ReadFull(...)
/home/wxh/.local/go/src/io/io.go:351
net/http.http2readFrameHeader({0xc0001aad60?, 0x9?, 0xc0004d5df0?}, {0x7c3760?, 0xc0001af1a0?})
/home/wxh/.local/go/src/net/http/h2_bundle.go:1565 +0x6e
net/http.(*http2Framer).ReadFrame(0xc0001aad20)
/home/wxh/.local/go/src/net/http/h2_bundle.go:1829 +0x95
net/http.(*http2clientConnReadLoop).run(0xc0004d5f98)
/home/wxh/.local/go/src/net/http/h2_bundle.go:8875 +0x130
net/http.(*http2ClientConn).readLoop(0xc00009e180)
/home/wxh/.local/go/src/net/http/h2_bundle.go:8771 +0x6f
created by net/http.(*http2Transport).newClientConn
/home/wxh/.local/go/src/net/http/h2_bundle.go:7478 +0xaaa
Goroutine 37 in state IO wait, with internal/poll.runtime_pollWait on top of the stack:
goroutine 37 [IO wait]:
internal/poll.runtime_pollWait(0x7f945c1e02a8, 0x72)
/home/wxh/.local/go/src/runtime/netpoll.go:305 +0x89
internal/poll.(*pollDesc).wait(0xc0003ca000?, 0xc000202000?, 0x0)
/home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
/home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).Read(0xc0003ca000, {0xc000202000, 0x1300, 0x1300})
/home/wxh/.local/go/src/internal/poll/fd_unix.go:167 +0x25a
net.(*netFD).Read(0xc0003ca000, {0xc000202000?, 0xc0004e6798?, 0xc0004c0808?})
/home/wxh/.local/go/src/net/fd_posix.go:55 +0x29
net.(*conn).Read(0xc000014028, {0xc000202000?, 0xc000136630?, 0x2c?})
/home/wxh/.local/go/src/net/net.go:183 +0x45
crypto/tls.(*atLeastReader).Read(0xc000276288, {0xc000202000?, 0x0?, 0x150fbb8ccb566149?})
/home/wxh/.local/go/src/crypto/tls/conn.go:787 +0x3d
bytes.(*Buffer).ReadFrom(0xc0000a0978, {0x7c3860, 0xc000276288})
/home/wxh/.local/go/src/bytes/buffer.go:202 +0x98
crypto/tls.(*Conn).readFromUntil(0xc0000a0700, {0x7c3b80?, 0xc000014028}, 0xc0004cc2c0?)
/home/wxh/.local/go/src/crypto/tls/conn.go:809 +0xe5
crypto/tls.(*Conn).readRecordOrCCS(0xc0000a0700, 0x0)
/home/wxh/.local/go/src/crypto/tls/conn.go:616 +0x116
crypto/tls.(*Conn).readRecord(...)
/home/wxh/.local/go/src/crypto/tls/conn.go:582
crypto/tls.(*Conn).Read(0xc0000a0700, {0xc00023c000, 0x1000, 0x11?})
/home/wxh/.local/go/src/crypto/tls/conn.go:1287 +0x16f
bufio.(*Reader).Read(0xc00022a2a0, {0xc00020e2e0, 0x9, 0xc0004c0d18?})
/home/wxh/.local/go/src/bufio/bufio.go:237 +0x1bb
io.ReadAtLeast({0x7c3760, 0xc00022a2a0}, {0xc00020e2e0, 0x9, 0x9}, 0x9)
/home/wxh/.local/go/src/io/io.go:332 +0x9a
io.ReadFull(...)
/home/wxh/.local/go/src/io/io.go:351
net/http.http2readFrameHeader({0xc00020e2e0?, 0x9?, 0xc0004c0df0?}, {0x7c3760?, 0xc00022a2a0?})
/home/wxh/.local/go/src/net/http/h2_bundle.go:1565 +0x6e
net/http.(*http2Framer).ReadFrame(0xc00020e2a0)
/home/wxh/.local/go/src/net/http/h2_bundle.go:1829 +0x95
net/http.(*http2clientConnReadLoop).run(0xc0004c0f98)
/home/wxh/.local/go/src/net/http/h2_bundle.go:8875 +0x130
net/http.(*http2ClientConn).readLoop(0xc00019e300)
/home/wxh/.local/go/src/net/http/h2_bundle.go:8771 +0x6f
created by net/http.(*http2Transport).newClientConn
/home/wxh/.local/go/src/net/http/h2_bundle.go:7478 +0xaaa
]
FAIL
exit status 1
Does anyone know how to address this issue?
Thanks!
If you have a module with a leak in func leak():
package foo
import (
"sync"
"time"
)
type O struct {
once *sync.Once
quit chan struct{}
}
func NewO() *O {
o := &O{
once: &sync.Once{},
quit: make(chan struct{}),
}
return o
}
func (o *O) leak() {
go func() {
d := 100 * time.Millisecond
for {
select {
case <-o.quit:
return
case <-time.After(2 * d):
time.Sleep(d)
}
}
}()
}
func (o *O) close() {
o.once.Do(func() {
close(o.quit)
})
}
func (*O) run(d time.Duration) {
time.Sleep(d)
}
and tests checking for leaks by running defer goleak.VerifyNone(t)
, that don't run leak(), it will show a leak in TestC, even if the leak is in TestB without defer goleak.VerifyNone(t)
:
package foo
import (
"testing"
"time"
"go.uber.org/goleak"
)
func TestA(t *testing.T) {
defer goleak.VerifyNone(t)
o := NewO()
defer o.close()
o.run(time.Second)
}
func TestB(t *testing.T) {
o := NewO()
o.leak()
o.run(time.Second)
}
func TestC(t *testing.T) {
defer goleak.VerifyNone(t)
o := NewO()
defer o.close()
o.run(time.Second)
}
It depends on order of execution of tests.
Here a test run:
% go test .
--- FAIL: TestC (1.45s)
foo_test.go:30: found unexpected goroutines:
[Goroutine 6 in state select, with foo.(*O).leak.func1 on top of the stack:
goroutine 6 [select]:
foo.(*O).leak.func1()
/tmp/go/goleak/foo.go:25 +0x85
created by foo.(*O).leak
/tmp/go/goleak/foo.go:22 +0x56
]
FAIL
FAIL foo 3.466s
FAIL
Hi, I'm trying to skip reporting rollbar goroutine like below:
func TestMain(m *testing.M) {
goleak.IgnoreAnyFunction("github.com/rollbar/rollbar-go.NewAsyncTransport.func1")
goleak.IgnoreAnyFunction("github.com/rollbar/rollbar-go.NewAsyncTransport")
goleak.VerifyTestMain(m)
os.Exit(testMain(m))
}
but it still does report about the leak
=== RUN TestE2E
Starting E2E test
--- PASS: TestE2E (1.00s)
PASS
goleak: Errors on successful test run: found unexpected goroutines:
[Goroutine 34 in state chan receive, with github.com/rollbar/rollbar-go.NewAsyncTransport.func1 on top of the stack:
github.com/rollbar/rollbar-go.NewAsyncTransport.func1()
/Users/sagar/go/pkg/mod/github.com/rollbar/[email protected]/async_transport.go:74 +0x8a
created by github.com/rollbar/rollbar-go.NewAsyncTransport in goroutine 1
/Users/sagar/go/pkg/mod/github.com/rollbar/[email protected]/async_transport.go:61 +0x198
]
FAIL
What possibly wrong Im doing?
Hello,
I am working at Manomano and we use gemnasium analyser to report securities issues.
We use zap logger and goleak is a dependency of zap.logger.
This little pr purpose you to update your yaml dependency to a fixed version.
Detail report:
| Severity | Unknown |
| Identifier | |
| URL | docker/cli#2117 |
| Scanner | Gemnasium |
| Message | XML Entity Expansion in gopkg.in/yaml.v2 |
| Package | gopkg.in/yaml.v2 v2.2.1 |
| Solution | Upgrade to version 2.2.3 or above. |
| File | go.sum |
PR link: #59
I just have a look the codes generally, my understanding is that check leak by compare goroutine number each time?
Could you make a doc what describe the theory or process of check leak? Thanks a lot
Hi, thanks for providing great package :)
BTW, I saw goleak
internal source and found below switch...case
:
Line 118 in 1874254
But, I used t.Parallel
func on my project testing. So, goleak
suggested:
found unexpected goroutines
Is it the expected behavior? Or, Should I adding goleak.IgnoreTopFunction("testing.(*T).Parallel")
to defer goleak.VerifyNoLeaks(t)
? (and, is it correct use case?)
tinygo as of release 0.22 does not support goleak; this isn't particularly surprising, as tinygo still only provides stubs for several things goleak relies upon.
A number of apps - particularly, the one I'm trying to ship :-) - would pass tests under both go and tinygo if goleak sensed the tinygo build constraint and provided a minimal stub while tinygo matures.
This would be an elegant way to reduce friction for goleak users who must pass tests with both go and tinygo.
I'll provide a pull request with the simple change required. I think this is sufficient; works for my app, at least.
The go/lint dependency removal is important for Kubernetes. Can you perhaps tag a v1.2.1 release?
#94 would also be useful, but not crucial - the current workaround is to loop around goleak.Find.
Within a test, the recommendation is to use defer goleak.VerifyNone(t)
. However, this can't be used inside of a test helper. We may want to support t.Cleanup
, possibly via a new method, so this issue is to investigate what we should do.
Is there any plan to create a new tag fallowing the semantic versioning? This since the latest tag (v0.10.0
) was almost 2 years ago, which go get
will use unless a commit is specified.
I see there is a V1 PR already merged (#27), but if V1 it's still not stable/ready, would it be possible to tag the bug fix for t.Paralell (#25) under something like v0.10.1
or v0.11.0
?
Is this project accepting open contributions?
The vision of this project is great, we (contributors) can work towards making this better.
I'd like to verify that there are no goroutines leaked in my test, but only for goroutines where my test itself is an ancestor goroutine. AFAIK, this is not what goleak currently does. It looks at all goroutines, which means it doesn't work in parallel, and it doesn't work for many globally initialized goroutines like those created in the init function of some imported package.
There is a tracebackancestors option that can be passed to the GODEBUG environment variable (documented here, withe the original accepted proposal here. This option adds ancestry metadata to goroutines, which should make the functionality I'm looking for possible.
Are there any plans to add this functionality to goleak?
The readme currently out of date, it uses
defer goleak.VerifyNoLeaks(t)
as an example usage. As of #27 this method was renamed to VerifyNone
https://github.com/uber-go/goleak/pull/27/files#diff-36b97ca3b1fb182af2f0e9faaedd21deR76
Readme explains this is compatible with Go 1.5+
.
However, the latest version v1.2.0
only works on Go 1.18+
.
Sample code:
package main
import (
"testing"
"go.uber.org/goleak"
)
func TestLeak(t *testing.T) {
defer goleak.VerifyNone(t)
}
$ go version
go version go1.13.15 linux/amd64
$ go test
# go.uber.org/goleak
/go/pkg/mod/go.uber.org/[email protected]/options.go:115:3: undefined: isTraceStack
note: module requires Go 1.18
FAIL example.com/foo [build failed]
The previous version v1.1.12
works expectedly. This seems due to #79.
Is current version only compatible with Go 1.18+?
os platform: ubuntu 20.04
go version: 1.19.7
Can someone advise me how to pass the test?
Is the problem caused by the running time FAIL demo/test 1.169s
?
package test
import (
"fmt"
"net/http"
"testing"
"go.uber.org/goleak"
)
func TestXxx(t *testing.T) {
defer goleak.VerifyNone(t)
resp, err := http.Get("https://www.microsoft.com")
if err != nil {
t.Fail()
}
defer resp.Body.Close()
fmt.Println(resp.StatusCode)
}
OUTPUT:
go test
200
--- FAIL: TestXxx (1.16s)
m_test.go:19: found unexpected goroutines:
[Goroutine 13 in state IO wait, with internal/poll.runtime_pollWait on top of the stack:
goroutine 13 [IO wait]:
internal/poll.runtime_pollWait(0x7f5fc173dff0, 0x72)
/home/ubuntu/go/src/runtime/netpoll.go:305 +0x89
internal/poll.(*pollDesc).wait(0xc0003b0480?, 0xc000284a00?, 0x0)
/home/ubuntu/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
/home/ubuntu/go/src/internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).Read(0xc0003b0480, {0xc000284a00, 0x2500, 0x2500})
/home/ubuntu/go/src/internal/poll/fd_unix.go:167 +0x25a
net.(*netFD).Read(0xc0003b0480, {0xc000284a00?, 0xc00040ad60?, 0xc000285409?})
/home/ubuntu/go/src/net/fd_posix.go:55 +0x29
net.(*conn).Read(0xc000014008, {0xc000284a00?, 0x56?, 0x0?})
/home/ubuntu/go/src/net/net.go:183 +0x45
crypto/tls.(*atLeastReader).Read(0xc0002d0018, {0xc000284a00?, 0xc0003e1520?, 0x4e12a8?})
/home/ubuntu/go/src/crypto/tls/conn.go:787 +0x3d
bytes.(*Buffer).ReadFrom(0xc000798cf8, {0xb063e0, 0xc0002d0018})
/home/ubuntu/go/src/bytes/buffer.go:202 +0x98
crypto/tls.(*Conn).readFromUntil(0xc000798a80, {0xb06700?, 0xc000014008}, 0x1afc?)
/home/ubuntu/go/src/crypto/tls/conn.go:809 +0xe5
crypto/tls.(*Conn).readRecordOrCCS(0xc000798a80, 0x0)
/home/ubuntu/go/src/crypto/tls/conn.go:616 +0x116
crypto/tls.(*Conn).readRecord(...)
/home/ubuntu/go/src/crypto/tls/conn.go:582
crypto/tls.(*Conn).Read(0xc000798a80, {0xc00028f000, 0x1000, 0x670a80?})
/home/ubuntu/go/src/crypto/tls/conn.go:1315 +0x16f
bufio.(*Reader).Read(0xc0000aa720, {0xc0001de2e0, 0x9, 0x67e4a5?})
/home/ubuntu/go/src/bufio/bufio.go:237 +0x1bb
io.ReadAtLeast({0xb062e0, 0xc0000aa720}, {0xc0001de2e0, 0x9, 0x9}, 0x9)
/home/ubuntu/go/src/io/io.go:332 +0x9a
io.ReadFull(...)
/home/ubuntu/go/src/io/io.go:351
net/http.http2readFrameHeader({0xc0001de2e0?, 0x9?, 0xc0002ae060?}, {0xb062e0?, 0xc0000aa720?})
/home/ubuntu/go/src/net/http/h2_bundle.go:1565 +0x6e
net/http.(*http2Framer).ReadFrame(0xc0001de2a0)
/home/ubuntu/go/src/net/http/h2_bundle.go:1829 +0x95
net/http.(*http2clientConnReadLoop).run(0xc000063f98)
/home/ubuntu/go/src/net/http/h2_bundle.go:8874 +0x130
net/http.(*http2ClientConn).readLoop(0xc00017ed80)
/home/ubuntu/go/src/net/http/h2_bundle.go:8770 +0x6f
created by net/http.(*http2Transport).newClientConn
/home/ubuntu/go/src/net/http/h2_bundle.go:7477 +0xaaa
]
FAIL
exit status 1
FAIL demo/test 1.169s
Currently, every call to goleak.Verify*
needs to specify any stacks to ignore. If there are known leaks which affect multiple packages, this results in duplication in each package specifying the same ignores.
We should investigate approaches to make this easier, as a strawman proposal:
Add AppendDefaultOptions
as an exported function that allows appending a default set of ignores, that can be called in some init
function, and can be shared for all tests by depending on the package that adds the default options.
I got some FP with backtrace looks like this
[Goroutine 1 in state chan receive, with testing.tRunner.func1 on top of the stack:
goroutine 1 [chan receive]:
testing.tRunner.func1()
C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:1542 +0x4a5
testing.tRunner(0xc0000376c0, 0xc000071c88)
C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:1582 +0x144
testing.runTests(0xc000055b80?, {0x16ac3a0, 0x1b, 0x1b}, {0xc00007c180?, 0x100c000071d10?, 0x0?})
C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:2034 +0x489
testing.(*M).Run(0xc000055b80)
C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:1906 +0x63a
main.main()
_testmain.go:101 +0x1aa
]
Indeed, these functions also occurs on the top of the stack, is them missed or by design?
testing.tRunner.func1"
"testing.(*F).Fuzz.func1"
"testing.runFuzzTests"
"testing.runFuzzing"
Considering that we may depend on some other repositories, but we don't care too much about those repos. An alternative would be to support regex filter.
TestMain can be used for setup and teardown logic. However, VerifyTestMain calls os.Exit
which disables to register teardown function by defer
. cc @prashantv
As stated in the title, when you invoke the test command with a trace option, the test always fails with a message concerning trace:
--- FAIL: TestAnd (0.45s)
leaks.go:78: found unexpected goroutines:
[Goroutine 6 in state trace reader (blocked), with runtime.goparkunlock on top of the stack:
goroutine 6 [trace reader (blocked)]:
runtime.goparkunlock(...)
c:/go/src/runtime/proc.go:310
Even when the test is empty like this one :
package main
import (
"testing"
"go.uber.org/goleak"
)
func TestAnd(t *testing.T) {
defer goleak.VerifyNone(t)
}
goleak.Verify
should be goleak.VerifyNoLeaks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.