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 or io: panic (reduced test case included) #7848

Closed
olov opened this issue Apr 23, 2014 · 3 comments
Closed

net/http or io: panic (reduced test case included) #7848

olov opened this issue Apr 23, 2014 · 3 comments

Comments

@olov
Copy link

olov commented Apr 23, 2014

What does 'go version' print?
o version go1.2 darwin/amd64

server.go:
package main

import (
    "io"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        io.WriteString(w, "Hello World\n")
    })
    http.ListenAndServe(":8100", nil)
}


crashproxy.go:
package main

import (
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    server, _ := url.Parse("http://127.0.0.1:8100";)
    http.Handle("/", httputil.NewSingleHostReverseProxy(server))
    http.ListenAndServe(":11111", nil)
}


% go run server.go &
% go build crashproxy.go # we need the executable below
% ./crashproxy


With these running, we'll POST a file to the hello server through the reverse proxy.
We'll send the crashproxy binary (5-10 MBs).

% curl -i -F "file=@crashproxy;filename=crashproxy" http://localhost:11111

Run that curl command a number of times (drum arrow-up / enter quickly) until crashproxy
panics. I believe the crash is unrelated to the reverse proxy code but it was easier to
demonstrate using it.

[My real-world code that triggered this panic had a (node.js) server process that
sometimes crashed (upon file POST) and then sometimes took a (golang) reverse proxy with
it. This test case doesn't feature a crashing server process because one that just
responded directly seemed to do the trick as well]

Panic log follows:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x518c0]

goroutine 40 [running]:
runtime.panic(0x1f8d60, 0x476df9)
    /usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
bufio.(*Reader).Read(0xc210037660, 0xc2100ca000, 0x1000, 0x1000, 0x1000, ...)
    /usr/local/go/src/pkg/bufio/bufio.go:152 +0x100
io.(*LimitedReader).Read(0xc2100a8ee0, 0xc2100ca000, 0x1000, 0x1000, 0x1000, ...)
    /usr/local/go/src/pkg/io/io.go:398 +0xbb
net/http.(*body).Read(0xc2100c7030, 0xc2100ca000, 0x1000, 0x1000, 0x1000, ...)
    /usr/local/go/src/pkg/net/http/transfer.go:534 +0x96
net/http.(*expectContinueReader).Read(0xc2100a8f00, 0xc2100ca000, 0x1000, 0x1000,
0xc2100ca000, ...)
    /usr/local/go/src/pkg/net/http/server.go:520 +0x11a
io.(*LimitedReader).Read(0xc2100a8060, 0xc2100ca000, 0x1000, 0x1000, 0xbf, ...)
    /usr/local/go/src/pkg/io/io.go:398 +0xbb
bufio.(*Writer).ReadFrom(0xc21004e4c0, 0x55f458, 0xc2100a8060, 0xa6ed1, 0x0, ...)
    /usr/local/go/src/pkg/bufio/bufio.go:622 +0x15a
io.Copy(0x55f588, 0xc21004e4c0, 0x55f458, 0xc2100a8060, 0x0, ...)
    /usr/local/go/src/pkg/io/io.go:348 +0x124
net/http.(*transferWriter).WriteBody(0xc2100c62a0, 0x55f588, 0xc21004e4c0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/transfer.go:196 +0x57c
net/http.(*Request).write(0xc2100361a0, 0x55f588, 0xc21004e4c0, 0x0, 0xc2100c7150, ...)
    /usr/local/go/src/pkg/net/http/request.go:400 +0x7e4
net/http.(*persistConn).writeLoop(0xc210058780)
    /usr/local/go/src/pkg/net/http/transport.go:797 +0x185
created by net/http.(*Transport).dialConn
    /usr/local/go/src/pkg/net/http/transport.go:529 +0x61e

goroutine 1 [IO wait]:
net.runtime_pollWait(0x55f300, 0x72, 0x0)
    /private/tmp/bindist142506725/go/src/pkg/runtime/netpoll.goc:116 +0x6a
net.(*pollDesc).Wait(0xc21004f140, 0x72, 0x55e098, 0x23)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:81 +0x34
net.(*pollDesc).WaitRead(0xc21004f140, 0x23, 0x55e098)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:86 +0x30
net.(*netFD).accept(0xc21004f0e0, 0x2a8fb8, 0x0, 0x55e098, 0x23)
    /usr/local/go/src/pkg/net/fd_unix.go:382 +0x2c2
net.(*TCPListener).AcceptTCP(0xc2100001e0, 0x3760b, 0x59ee10, 0x3760b)
    /usr/local/go/src/pkg/net/tcpsock_posix.go:233 +0x47
net.(*TCPListener).Accept(0xc2100001e0, 0x55f3a8, 0xc210000aa0, 0xc210058580, 0x0)
    /usr/local/go/src/pkg/net/tcpsock_posix.go:243 +0x27
net/http.(*Server).Serve(0xc21001e410, 0x55e360, 0xc2100001e0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:1622 +0x91
net/http.(*Server).ListenAndServe(0xc21001e410, 0xc21001e410, 0xc21004b4a0)
    /usr/local/go/src/pkg/net/http/server.go:1612 +0xa0
net/http.ListenAndServe(0x237c00, 0x6, 0x0, 0x0, 0x0, ...)
    /usr/local/go/src/pkg/net/http/server.go:1677 +0x6d
main.main()
    /Users/olov/projects/mcs/goproxy/src/crashproxy.go:12 +0xad

goroutine 3 [IO wait]:
net.runtime_pollWait(0x55f258, 0x72, 0x0)
    /private/tmp/bindist142506725/go/src/pkg/runtime/netpoll.goc:116 +0x6a
net.(*pollDesc).Wait(0xc21004f300, 0x72, 0x55e098, 0x23)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:81 +0x34
net.(*pollDesc).WaitRead(0xc21004f300, 0x23, 0x55e098)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:86 +0x30
net.(*netFD).Read(0xc21004f2a0, 0xc21005a000, 0x1000, 0x1000, 0x0, ...)
    /usr/local/go/src/pkg/net/fd_unix.go:204 +0x2a0
net.(*conn).Read(0xc210000200, 0xc21005a000, 0x1000, 0x1000, 0x0, ...)
    /usr/local/go/src/pkg/net/net.go:122 +0xc5
net/http.(*liveSwitchReader).Read(0xc2100582a8, 0xc21005a000, 0x1000, 0x1000, 0x5bab48,
...)
    /usr/local/go/src/pkg/net/http/server.go:204 +0xa5
io.(*LimitedReader).Read(0xc21004b4e0, 0xc21005a000, 0x1000, 0x1000, 0xb434, ...)
    /usr/local/go/src/pkg/io/io.go:398 +0xbb
bufio.(*Reader).fill(0xc2100370c0)
    /usr/local/go/src/pkg/bufio/bufio.go:91 +0x110
bufio.(*Reader).ReadSlice(0xc2100370c0, 0xa, 0x0, 0x0, 0x0, ...)
    /usr/local/go/src/pkg/bufio/bufio.go:274 +0x204
bufio.(*Reader).ReadLine(0xc2100370c0, 0x0, 0x0, 0x0, 0x0, ...)
    /usr/local/go/src/pkg/bufio/bufio.go:305 +0x63
net/textproto.(*Reader).readLineSlice(0xc21001da50, 0x555000, 0x199fe0, 0x5bace8,
0x20752, ...)
    /usr/local/go/src/pkg/net/textproto/reader.go:55 +0x61
net/textproto.(*Reader).ReadLine(0xc21001da50, 0xc2100441a0, 0x0, 0xc21005b000, 0x0)
    /usr/local/go/src/pkg/net/textproto/reader.go:36 +0x27
net/http.ReadRequest(0xc2100370c0, 0xc2100441a0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/request.go:526 +0x88
net/http.(*conn).readRequest(0xc210058280, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:575 +0x1bb
net/http.(*conn).serve(0xc210058280)
    /usr/local/go/src/pkg/net/http/server.go:1123 +0x3b4
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1644 +0x28b

goroutine 33 [sleep]:
time.Sleep(0x1dcd6500)
    /private/tmp/bindist142506725/go/src/pkg/runtime/time.goc:31 +0x31
net/http.(*conn).closeWriteAndWait(0xc210058480)
    /usr/local/go/src/pkg/net/http/server.go:1072 +0x75
net/http.(*conn).serve(0xc210058480)
    /usr/local/go/src/pkg/net/http/server.go:1174 +0x81d
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1644 +0x28b

goroutine 37 [sleep]:
time.Sleep(0x1dcd6500)
    /private/tmp/bindist142506725/go/src/pkg/runtime/time.goc:31 +0x31
net/http.(*conn).closeWriteAndWait(0xc210058580)
    /usr/local/go/src/pkg/net/http/server.go:1072 +0x75
net/http.(*conn).serve(0xc210058580)
    /usr/local/go/src/pkg/net/http/server.go:1174 +0x81d
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1644 +0x28b
exit status 2
@olov
Copy link
Author

olov commented Apr 23, 2014

Comment 1:

Just tried this on go 1.3 beta1 without panics, yay!
Is this related to the release notes item "The net/http package's Transport now closes
Request.Body consistently, even on error"? [although there doesn't seem to be a whole
lot of errors going on in server.go and crashproxy.go]

@ianlancetaylor
Copy link
Contributor

Comment 2:

There have been a number of bug fixes in net/http.  I'm going to close this as fixed in
1.3.  Please reopen if you can recreate it with 1.3 beta.

Status changed to Fixed.

@rsc
Copy link
Contributor

rsc commented May 21, 2014

Comment 3:

Issue #7527 has been merged into this issue.

@olov olov added the fixed label May 21, 2014
@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

4 participants