Skip to content
New issue

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

net/http: leaked Transport in tests #7847

Closed
gpaul opened this issue Apr 23, 2014 · 8 comments
Closed

net/http: leaked Transport in tests #7847

gpaul opened this issue Apr 23, 2014 · 8 comments
Milestone

Comments

@gpaul
Copy link
Contributor

gpaul commented Apr 23, 2014

The net/http package tests fail quite consistently with 
"Test appears to have leaked a Transport"

What does 'go version' print?
go version devel +f613443bb13a Tue Apr 22 21:12:15 2014 -0700 linux/amd64
(tip)

What steps reproduce the problem?
Run the following tests a few times. It reproduces roughly once every 10 runs.
go test -v net/http
-run="TestTransportCancelRequest$|TestTransportSocketLateBinding"

What happened?
=== RUN TestTransportCancelRequestInDial
--- PASS: TestTransportCancelRequestInDial (0.00 seconds)
=== RUN TestTransportSocketLateBinding
--- FAIL: TestTransportSocketLateBinding (1.21 seconds)
    z_last_test.go:96: Test appears to have leaked a Transport:
        net.runtime_pollWait(0x7f2d5a7a0938, 0x72, 0x0)
            /home/gustav/go.tip/src/pkg/runtime/netpoll.goc:146 +0x66
        net.(*pollDesc).Wait(0xc208043020, 0x72, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/fd_poll_runtime.go:84 +0x46
        net.(*pollDesc).WaitRead(0xc208043020, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/fd_poll_runtime.go:89 +0x42
        net.(*netFD).Read(0xc208042fc0, 0xc20828f000, 0x1000, 0x1000, 0x0, 0x7f2d5a79f408, 0xb)
            /home/gustav/go.tip/src/pkg/net/fd_unix.go:232 +0x30e
        net.(*conn).Read(0xc20805c0f8, 0xc20828f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/net.go:122 +0xe7
        net/http.noteEOFReader.Read(0x7f2d5a7a0cb8, 0xc20805c0f8, 0xc208060688, 0xc20828f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/http/transport.go:1200 +0x7a
        net/http.(*noteEOFReader).Read(0xc208058e60, 0xc20828f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/http/chunked.go:1 +0xdf
        bufio.(*Reader).fill(0xc208046c00)
            /home/gustav/go.tip/src/pkg/bufio/bufio.go:97 +0x1a2
        bufio.(*Reader).Peek(0xc208046c00, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/bufio/bufio.go:132 +0x101
        net/http.(*persistConn).readLoop(0xc208060630)
            /home/gustav/go.tip/src/pkg/net/http/transport.go:779 +0x9e
        created by net/http.(*Transport).dialConn
            /home/gustav/go.tip/src/pkg/net/http/transport.go:597 +0x912
        
        net.runtime_pollWait(0x7f2d5a7a0a98, 0x72, 0x0)
            /home/gustav/go.tip/src/pkg/runtime/netpoll.goc:146 +0x66
        net.(*pollDesc).Wait(0xc2080431e0, 0x72, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/fd_poll_runtime.go:84 +0x46
        net.(*pollDesc).WaitRead(0xc2080431e0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/fd_poll_runtime.go:89 +0x42
        net.(*netFD).Read(0xc208043180, 0xc2084b1000, 0x1000, 0x1000, 0x0, 0x7f2d5a79f408, 0xb)
            /home/gustav/go.tip/src/pkg/net/fd_unix.go:232 +0x30e
        net.(*conn).Read(0xc20805c100, 0xc2084b1000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/net.go:122 +0xe7
        net/http.(*liveSwitchReader).Read(0xc208068628, 0xc2084b1000, 0x1000, 0x1000, 0x54cfbb, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/http/server.go:206 +0xc4
        io.(*LimitedReader).Read(0xc208058ee0, 0xc2084b1000, 0x1000, 0x1000, 0x7f2d5a793d80, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/io/io.go:399 +0xcd
        bufio.(*Reader).fill(0xc208046c60)
            /home/gustav/go.tip/src/pkg/bufio/bufio.go:97 +0x1a2
        bufio.(*Reader).ReadSlice(0xc208046c60, 0x53880a, 0x0, 0x0, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/bufio/bufio.go:295 +0x2ad
        bufio.(*Reader).ReadLine(0xc208046c60, 0x0, 0x0, 0x0, 0x7f2d5a794a00, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/bufio/bufio.go:313 +0x9c
        net/textproto.(*Reader).readLineSlice(0xc208292450, 0x0, 0x0, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/textproto/reader.go:55 +0x9d
        net/textproto.(*Reader).ReadLine(0xc208292450, 0x0, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/textproto/reader.go:36 +0x4b
        net/http.ReadRequest(0xc208046c60, 0xc208084820, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/http/request.go:556 +0xac
        net/http.(*conn).readRequest(0xc208068600, 0x0, 0x0, 0x0)
            /home/gustav/go.tip/src/pkg/net/http/server.go:577 +0x20b
        net/http.(*conn).serve(0xc208068600)
            /home/gustav/go.tip/src/pkg/net/http/server.go:1134 +0x57b
        created by net/http.(*Server).Serve
            /home/gustav/go.tip/src/pkg/net/http/server.go:1723 +0x2ea
        
        net/http.(*persistConn).writeLoop(0xc208060630)
            /home/gustav/go.tip/src/pkg/net/http/transport.go:882 +0x336
        created by net/http.(*Transport).dialConn
            /home/gustav/go.tip/src/pkg/net/http/transport.go:598 +0x92a
FAIL
exit status 1
FAIL    net/http    1.211s

What should have happened instead?
=== RUN TestTransportCancelRequestInDial
--- PASS: TestTransportCancelRequestInDial (0.00 seconds)
=== RUN TestTransportSocketLateBinding
--- PASS: TestTransportSocketLateBinding (0.45 seconds)
PASS
ok      net/http    0.455s

Please provide any additional information below.
$ uname -a
Linux gpaul-dell 3.13.9-100.fc19.x86_64 #1 SMP Fri Apr 4 00:51:59 UTC 2014 x86_64 x86_64
x86_64 GNU/Linux
@gpaul
Copy link
Contributor Author

gpaul commented Apr 23, 2014

Comment 1:

It looks like a request is cancelled while its dialling and 
net/http/transport.go:459: handlePendingDial() 
then waits for it and keeps it around with putIdleConn().
Perhaps these CancelRequest tests should disable keepalives so the conn is closed on
entry to putIdleConn.

@ianlancetaylor
Copy link
Contributor

Comment 2:

Labels changed: added repo-main, release-go1.3.

@gpaul
Copy link
Contributor Author

gpaul commented Apr 24, 2014

Comment 3:

This reproduces with TestTransportSocketLateBinding on its own.
The test ends with a call to dialGate<-true, which leads to a race between the server
shutting down in a defer, and the custom Dial waiting on dialGate succeeding.
When the server shuts down first, the dial() in (*Transport).dialConn returns an error
and the test passes with no zombie goroutines.
When the dialGate<-true unblocks the pending Dial before the server shuts down, the
t.dial() succeeds and (*Transport).dialConn() runs to its end, at which point it
launches a readLoop goroutine which is never closed.
Depending on what this test is testing, pick one and wait for it to finish before doing
the other.

@rsc
Copy link
Contributor

rsc commented May 9, 2014

Comment 4:

Brad, any ideas?

Status changed to Accepted.

@bradfitz
Copy link
Contributor

bradfitz commented May 9, 2014

Comment 5:

I thought somebody was going to send a CL, but I can.

@gopherbot
Copy link

Comment 6 by fabrizio.milo:

If I understood the issue I think this should fix it:
https://golang.org/cl/96230044

@gopherbot
Copy link

Comment 7:

CL https://golang.org/cl/96230044 mentions this issue.

@bradfitz
Copy link
Contributor

Comment 8:

This issue was closed by revision 7e8bc47.

Status changed to Fixed.

@rsc rsc added this to the Go1.3 milestone Apr 14, 2015
@rsc rsc removed the release-go1.3 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants