I use a server to broadcast / echo messages from clients to all connected clients. The server only broadcasts the first message it receives, although it still receives messages - as fmt.Println([]byte(buf)) still prints new messages from the clients - and new clients can connect (but their messages also won't be broadcasted).
After some feedback, it looks like one goroutine is stuck. But so far I've been unable to find which one. Help is really appreciated.
The server:
package main
import (
"crypto/tls"
"encoding/binary"
"fmt"
"io"
"log"
"net"
"net/http"
_ "net/http/pprof"
)
type client chan<- string // an outgoing message channel
var (
entering = make(chan client, 10)
leaving = make(chan client, 10)
messages = make(chan string, 10) // all incoming client messages
)
func broadcaster() {
clients := make(map[client]bool) // all connected clients
for {
select {
case msg := <-messages:
// Broadcast incoming message to all clients' outgoing message channels.
for cli := range clients {
cli <- string(msg)
}
case cli := <-entering:
clients[cli] = true
case cli := <-leaving:
delete(clients, cli)
close(cli)
}
}
}
func handleConn(conn net.Conn) {
ch := make(chan string) // outgoing client messages
go clientWriter(conn, ch)
defer conn.Close()
entering <- ch
buf := make([]byte, 0, 2+64*1024)
for {
n, err := io.ReadFull(conn, buf[:2])
if err != nil {
fmt.Println(n, err)
leaving <- ch
return
}
msgLen := binary.BigEndian.Uint16(buf[0:2])
buf = buf[0 : 2+msgLen]
n, err = io.ReadFull(conn, buf[2:2+msgLen])
if err != nil {
fmt.Println(err)
leaving <- ch
return
}
messages <- string(buf)
fmt.Println([]byte(buf))
}
}
func clientWriter(conn net.Conn, ch <-chan string) {
for msg := range ch {
_, err := fmt.Fprintln(conn, msg)
if err != nil {
fmt.Println(err)
}
}
}
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
cer, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Println(err)
return
}
config := &tls.Config{
Certificates: []tls.Certificate{cer},
// Reject any TLS certificate that cannot be validated
//ClientAuth: tls.RequireAndVerifyClientCert,
// PFS, this will reject client with RSA certificates
CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
// Force it server side
PreferServerCipherSuites: true,
// TLS 1.2
MinVersion: tls.VersionTLS12}
listener, err := tls.Listen("tcp", "localhost:443", config)
if err != nil {
log.Fatal(err)
}
go broadcaster()
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
continue
}
go handleConn(conn)
}
}
My best guess is that the message channel is stuck - but I can't identify where. Help is really appreciated.
The client sends []bytes with [0, encrypted-message-length, encrypted-message], e.g. [0 52 155 84 146 8 228 90 28 41 88 33 178 143 243 243 160 255 180 73 20 43 129 155 132 255 207 10 9 130 54 216 44 38 141 101 17 125 101 4 62 228 221 158 196 41 163 227 253 71 179 172 143 225]
Update1: Sorry, I'm not good in debugging. Here are the full goroutine stack dumps (working and not working). The difference seems to me, that goroutine 8 was "runnable", while goroutine 9 is "IO wait" with "runtime_pollWait". Any ideas how to resolve it?
After server starts: Without any prior input from client (except connecting). In this state, the broadcast will work once.
goroutine 12 [running]:
runtime/pprof.writeGoroutineStacks(0x7da840, 0xc42035e0e0, 0x411a69, 0xc420150570)
/usr/lib/go-1.10/src/runtime/pprof/pprof.go:650 +0xa7
runtime/pprof.writeGoroutine(0x7da840, 0xc42035e0e0, 0x2, 0xc42006c000, 0x7da640)
/usr/lib/go-1.10/src/runtime/pprof/pprof.go:639 +0x44
runtime/pprof.(*Profile).WriteTo(0x980840, 0x7da840, 0xc42035e0e0, 0x2, 0xc42035e0e0, 0x7998f5)
/usr/lib/go-1.10/src/runtime/pprof/pprof.go:310 +0x3e4
net/http/pprof.handler.ServeHTTP(0xc42001a0a1, 0x9, 0x7dd620, 0xc42035e0e0, 0xc420254200)
/usr/lib/go-1.10/src/net/http/pprof/pprof.go:243 +0x20d
net/http/pprof.Index(0x7dd620, 0xc42035e0e0, 0xc420254200)
/usr/lib/go-1.10/src/net/http/pprof/pprof.go:254 +0x1d1
net/http.HandlerFunc.ServeHTTP(0x7b02a8, 0x7dd620, 0xc42035e0e0, 0xc420254200)
/usr/lib/go-1.10/src/net/http/server.go:1947 +0x44
net/http.(*ServeMux).ServeHTTP(0x98dda0, 0x7dd620, 0xc42035e0e0, 0xc420254200)
/usr/lib/go-1.10/src/net/http/server.go:2337 +0x130
net/http.serverHandler.ServeHTTP(0xc42016c000, 0x7dd620, 0xc42035e0e0, 0xc420254200)
/usr/lib/go-1.10/src/net/http/server.go:2694 +0xbc
net/http.(*conn).serve(0xc4201640a0, 0x7dd8e0, 0xc42014c300)
/usr/lib/go-1.10/src/net/http/server.go:1830 +0x651
created by net/http.(*Server).Serve
/usr/lib/go-1.10/src/net/http/server.go:2795 +0x27b
goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x7f84564f8e30, 0x72, 0x0)
/usr/lib/go-1.10/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc4201b0118, 0x72, 0xc4200a2000, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc4201b0118, 0xffffffffffffff00, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Accept(0xc4201b0100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_unix.go:372 +0x1a8
net.(*netFD).accept(0xc4201b0100, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc42000e018, 0x4122b8, 0x380, 0x78f260)
/usr/lib/go-1.10/src/net/tcpsock_posix.go:136 +0x2e
net.(*TCPListener).Accept(0xc42000e018, 0x4356c4, 0xc420181da0, 0x457610, 0xc420181de0)
/usr/lib/go-1.10/src/net/tcpsock.go:259 +0x49
crypto/tls.(*listener).Accept(0xc42010cd80, 0x7afee0, 0x7ded20, 0xc4200e6000, 0x0)
/usr/lib/go-1.10/src/crypto/tls/tls.go:52 +0x37
main.main()
/home/hendrik/Dropbox/go/chat/server/server.go:109 +0x2ca
goroutine 20 [IO wait]:
internal/poll.runtime_pollWait(0x7f84564f8d60, 0x72, 0xc42020baa8)
/usr/lib/go-1.10/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc42015c098, 0x72, 0xffffffffffffff00, 0x7db3a0, 0x9515e0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc42015c098, 0xc4200d6400, 0x400, 0x400)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Read(0xc42015c080, 0xc4200d6400, 0x400, 0x400, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_unix.go:157 +0x17d
net.(*netFD).Read(0xc42015c080, 0xc4200d6400, 0x400, 0x400, 0x57515a, 0xc42015c080, 0xc420202180)
/usr/lib/go-1.10/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc420156020, 0xc4200d6400, 0x400, 0x400, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/net/net.go:176 +0x6a
crypto/tls.(*block).readFromUntil(0xc420150330, 0x7f84564feae0, 0xc420156020, 0x5, 0xc420156020, 0x5d626a)
/usr/lib/go-1.10/src/crypto/tls/conn.go:493 +0x96
crypto/tls.(*Conn).readRecord(0xc4200e6000, 0x7b0717, 0xc4200e6120, 0x98b7c0)
/usr/lib/go-1.10/src/crypto/tls/conn.go:595 +0xe0
crypto/tls.(*Conn).Read(0xc4200e6000, 0xc4201e6000, 0x2, 0x10002, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/crypto/tls/conn.go:1156 +0x100
io.ReadAtLeast(0x7f84564feac0, 0xc4200e6000, 0xc4201e6000, 0x2, 0x10002, 0x2, 0x786f60, 0x6d8e00, 0x7f84564feac0)
/usr/lib/go-1.10/src/io/io.go:309 +0x86
io.ReadFull(0x7f84564feac0, 0xc4200e6000, 0xc4201e6000, 0x2, 0x10002, 0x10002, 0x6863ee, 0x1)
/usr/lib/go-1.10/src/io/io.go:327 +0x58
main.handleConn(0x7ded20, 0xc4200e6000)
/home/hendrik/Dropbox/go/chat/server/server.go:52 +0x27d
created by main.main
/home/hendrik/Dropbox/go/chat/server/server.go:115 +0x350
goroutine 4 [IO wait]:
internal/poll.runtime_pollWait(0x7f84564f8f00, 0x72, 0x0)
/usr/lib/go-1.10/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc4201b0098, 0x72, 0xc42014c000, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc4201b0098, 0xffffffffffffff00, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Accept(0xc4201b0080, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_unix.go:372 +0x1a8
net.(*netFD).accept(0xc4201b0080, 0xc420164120, 0xc42003edf0, 0x402b98)
/usr/lib/go-1.10/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc420156048, 0xc42003ee20, 0x401af7, 0xc420164120)
/usr/lib/go-1.10/src/net/tcpsock_posix.go:136 +0x2e
net.(*TCPListener).AcceptTCP(0xc420156048, 0xc42003ee68, 0xc42003ee70, 0x18)
/usr/lib/go-1.10/src/net/tcpsock.go:246 +0x49
net/http.tcpKeepAliveListener.Accept(0xc420156048, 0x7b00a8, 0xc4201640a0, 0x7dd9a0, 0xc420150750)
/usr/lib/go-1.10/src/net/http/server.go:3216 +0x2f
net/http.(*Server).Serve(0xc42016c000, 0x7dd820, 0xc420156048, 0x0, 0x0)
/usr/lib/go-1.10/src/net/http/server.go:2770 +0x1a5
net/http.(*Server).ListenAndServe(0xc42016c000, 0xc42016c000, 0x0)
/usr/lib/go-1.10/src/net/http/server.go:2711 +0xa9
net/http.ListenAndServe(0x79a39f, 0xe, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/net/http/server.go:2969 +0x7a
main.main.func1()
/home/hendrik/Dropbox/go/chat/server/server.go:83 +0x3e
created by main.main
/home/hendrik/Dropbox/go/chat/server/server.go:82 +0x4a
goroutine 36 [runnable]:
net/http.(*connReader).backgroundRead(0xc4201508d0)
/usr/lib/go-1.10/src/net/http/server.go:667
created by net/http.(*connReader).startBackgroundRead
/usr/lib/go-1.10/src/net/http/server.go:664 +0xce
goroutine 11 [select]:
main.broadcaster()
/home/hendrik/Dropbox/go/chat/server/server.go:25 +0x193
created by main.main
/home/hendrik/Dropbox/go/chat/server/server.go:107 +0x2b0
goroutine 21 [chan receive]:
main.clientWriter(0x7ded20, 0xc4200e6000, 0xc42007a120)
/home/hendrik/Dropbox/go/chat/server/server.go:73 +0x52
created by main.handleConn
/home/hendrik/Dropbox/go/chat/server/server.go:46 +0x89
after one broadcast (broadcast won't work): This is the state after one broadcast. Server won't broadcast any more messages.
goroutine 12 [running]:
runtime/pprof.writeGoroutineStacks(0x7da840, 0xc42035e1c0, 0x411a69, 0xc4201507e0)
/usr/lib/go-1.10/src/runtime/pprof/pprof.go:650 +0xa7
runtime/pprof.writeGoroutine(0x7da840, 0xc42035e1c0, 0x2, 0xc420468000, 0x7da640)
/usr/lib/go-1.10/src/runtime/pprof/pprof.go:639 +0x44
runtime/pprof.(*Profile).WriteTo(0x980840, 0x7da840, 0xc42035e1c0, 0x2, 0xc42035e1c0, 0x7998f5)
/usr/lib/go-1.10/src/runtime/pprof/pprof.go:310 +0x3e4
net/http/pprof.handler.ServeHTTP(0xc42001a2e1, 0x9, 0x7dd620, 0xc42035e1c0, 0xc420146100)
/usr/lib/go-1.10/src/net/http/pprof/pprof.go:243 +0x20d
net/http/pprof.Index(0x7dd620, 0xc42035e1c0, 0xc420146100)
/usr/lib/go-1.10/src/net/http/pprof/pprof.go:254 +0x1d1
net/http.HandlerFunc.ServeHTTP(0x7b02a8, 0x7dd620, 0xc42035e1c0, 0xc420146100)
/usr/lib/go-1.10/src/net/http/server.go:1947 +0x44
net/http.(*ServeMux).ServeHTTP(0x98dda0, 0x7dd620, 0xc42035e1c0, 0xc420146100)
/usr/lib/go-1.10/src/net/http/server.go:2337 +0x130
net/http.serverHandler.ServeHTTP(0xc42016c000, 0x7dd620, 0xc42035e1c0, 0xc420146100)
/usr/lib/go-1.10/src/net/http/server.go:2694 +0xbc
net/http.(*conn).serve(0xc4201640a0, 0x7dd8e0, 0xc42014c300)
/usr/lib/go-1.10/src/net/http/server.go:1830 +0x651
created by net/http.(*Server).Serve
/usr/lib/go-1.10/src/net/http/server.go:2795 +0x27b
goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x7f84564f8e30, 0x72, 0x0)
/usr/lib/go-1.10/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc4201b0118, 0x72, 0xc4200a2000, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc4201b0118, 0xffffffffffffff00, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Accept(0xc4201b0100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_unix.go:372 +0x1a8
net.(*netFD).accept(0xc4201b0100, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc42000e018, 0x4122b8, 0x380, 0x78f260)
/usr/lib/go-1.10/src/net/tcpsock_posix.go:136 +0x2e
net.(*TCPListener).Accept(0xc42000e018, 0x4356c4, 0xc420181da0, 0x457610, 0xc420181de0)
/usr/lib/go-1.10/src/net/tcpsock.go:259 +0x49
crypto/tls.(*listener).Accept(0xc42010cd80, 0x7afee0, 0x7ded20, 0xc4200e6000, 0x0)
/usr/lib/go-1.10/src/crypto/tls/tls.go:52 +0x37
main.main()
/home/hendrik/Dropbox/go/chat/server/server.go:109 +0x2ca
goroutine 20 [IO wait]:
internal/poll.runtime_pollWait(0x7f84564f8d60, 0x72, 0xc42020baa8)
/usr/lib/go-1.10/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc42015c098, 0x72, 0xffffffffffffff00, 0x7db3a0, 0x9515e0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc42015c098, 0xc4200d6400, 0x400, 0x400)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Read(0xc42015c080, 0xc4200d6400, 0x400, 0x400, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_unix.go:157 +0x17d
net.(*netFD).Read(0xc42015c080, 0xc4200d6400, 0x400, 0x400, 0x2, 0x80, 0x82)
/usr/lib/go-1.10/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc420156020, 0xc4200d6400, 0x400, 0x400, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/net/net.go:176 +0x6a
crypto/tls.(*block).readFromUntil(0xc420150330, 0x7f84564feae0, 0xc420156020, 0x5, 0xc420156020, 0x1)
/usr/lib/go-1.10/src/crypto/tls/conn.go:493 +0x96
crypto/tls.(*Conn).readRecord(0xc4200e6000, 0x7b0717, 0xc4200e6120, 0x0)
/usr/lib/go-1.10/src/crypto/tls/conn.go:595 +0xe0
crypto/tls.(*Conn).Read(0xc4200e6000, 0xc4201e6000, 0x2, 0x10002, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/crypto/tls/conn.go:1156 +0x100
io.ReadAtLeast(0x7f84564feac0, 0xc4200e6000, 0xc4201e6000, 0x2, 0x10002, 0x2, 0x786f60, 0x0, 0x7f84564feac0)
/usr/lib/go-1.10/src/io/io.go:309 +0x86
io.ReadFull(0x7f84564feac0, 0xc4200e6000, 0xc4201e6000, 0x2, 0x10002, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/io/io.go:327 +0x58
main.handleConn(0x7ded20, 0xc4200e6000)
/home/hendrik/Dropbox/go/chat/server/server.go:52 +0x27d
created by main.main
/home/hendrik/Dropbox/go/chat/server/server.go:115 +0x350
goroutine 4 [IO wait]:
internal/poll.runtime_pollWait(0x7f84564f8f00, 0x72, 0x0)
/usr/lib/go-1.10/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc4201b0098, 0x72, 0xc42014c000, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc4201b0098, 0xffffffffffffff00, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Accept(0xc4201b0080, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/internal/poll/fd_unix.go:372 +0x1a8
net.(*netFD).accept(0xc4201b0080, 0xc420164120, 0xc42003edf0, 0x402b98)
/usr/lib/go-1.10/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc420156048, 0xc42003ee20, 0x401af7, 0xc420164120)
/usr/lib/go-1.10/src/net/tcpsock_posix.go:136 +0x2e
net.(*TCPListener).AcceptTCP(0xc420156048, 0xc42003ee68, 0xc42003ee70, 0x18)
/usr/lib/go-1.10/src/net/tcpsock.go:246 +0x49
net/http.tcpKeepAliveListener.Accept(0xc420156048, 0x7b00a8, 0xc4201640a0, 0x7dd9a0, 0xc420150750)
/usr/lib/go-1.10/src/net/http/server.go:3216 +0x2f
net/http.(*Server).Serve(0xc42016c000, 0x7dd820, 0xc420156048, 0x0, 0x0)
/usr/lib/go-1.10/src/net/http/server.go:2770 +0x1a5
net/http.(*Server).ListenAndServe(0xc42016c000, 0xc42016c000, 0x0)
/usr/lib/go-1.10/src/net/http/server.go:2711 +0xa9
net/http.ListenAndServe(0x79a39f, 0xe, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.10/src/net/http/server.go:2969 +0x7a
main.main.func1()
/home/hendrik/Dropbox/go/chat/server/server.go:83 +0x3e
created by main.main
/home/hendrik/Dropbox/go/chat/server/server.go:82 +0x4a
goroutine 37 [runnable]:
net/http.(*connReader).backgroundRead(0xc4201508d0)
/usr/lib/go-1.10/src/net/http/server.go:667
created by net/http.(*connReader).startBackgroundRead
/usr/lib/go-1.10/src/net/http/server.go:664 +0xce
goroutine 11 [select]:
main.broadcaster()
/home/hendrik/Dropbox/go/chat/server/server.go:25 +0x193
created by main.main
/home/hendrik/Dropbox/go/chat/server/server.go:107 +0x2b0
goroutine 21 [chan receive]:
main.clientWriter(0x7ded20, 0xc4200e6000, 0xc42007a120)
/home/hendrik/Dropbox/go/chat/server/server.go:73 +0x52
created by main.handleConn
/home/hendrik/Dropbox/go/chat/server/server.go:46 +0x89
goroutine profile: total 7 - before any messages
1 @ 0x42e14a 0x42946a 0x428ae7 0x4d6f7b 0x4d6ffd 0x4d7e5d 0x563dcf 0x574eda 0x5c5096 0x5c55a0 0x5c8b40 0x471196 0x471308 0x6d907d 0x45ab71
# 0x428ae6 internal/poll.runtime_pollWait+0x56 /usr/lib/go-1.10/src/runtime/netpoll.go:173
# 0x4d6f7a internal/poll.(*pollDesc).wait+0x9a /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85
# 0x4d6ffc internal/poll.(*pollDesc).waitRead+0x3c /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90
# 0x4d7e5c internal/poll.(*FD).Read+0x17c /usr/lib/go-1.10/src/internal/poll/fd_unix.go:157
# 0x563dce net.(*netFD).Read+0x4e /usr/lib/go-1.10/src/net/fd_unix.go:202
# 0x574ed9 net.(*conn).Read+0x69 /usr/lib/go-1.10/src/net/net.go:176
# 0x5c5095 crypto/tls.(*block).readFromUntil+0x95 /usr/lib/go-1.10/src/crypto/tls/conn.go:493
# 0x5c559f crypto/tls.(*Conn).readRecord+0xdf /usr/lib/go-1.10/src/crypto/tls/conn.go:595
# 0x5c8b3f crypto/tls.(*Conn).Read+0xff /usr/lib/go-1.10/src/crypto/tls/conn.go:1156
# 0x471195 io.ReadAtLeast+0x85 /usr/lib/go-1.10/src/io/io.go:309
# 0x471307 io.ReadFull+0x57 /usr/lib/go-1.10/src/io/io.go:327
# 0x6d907c main.handleConn+0x27c /home/hendrik/Dropbox/go/chat/server/server.go:52
1 @ 0x42e14a 0x42946a 0x428ae7 0x4d6f7b 0x4d6ffd 0x4d93f8 0x5646e2 0x57e85e 0x57ce39 0x66271f 0x6614b5 0x661209 0x66224a 0x6d98ae 0x45ab71
# 0x428ae6 internal/poll.runtime_pollWait+0x56 /usr/lib/go-1.10/src/runtime/netpoll.go:173
# 0x4d6f7a internal/poll.(*pollDesc).wait+0x9a /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85
# 0x4d6ffc internal/poll.(*pollDesc).waitRead+0x3c /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90
# 0x4d93f7 internal/poll.(*FD).Accept+0x1a7 /usr/lib/go-1.10/src/internal/poll/fd_unix.go:372
# 0x5646e1 net.(*netFD).accept+0x41 /usr/lib/go-1.10/src/net/fd_unix.go:238
# 0x57e85d net.(*TCPListener).accept+0x2d /usr/lib/go-1.10/src/net/tcpsock_posix.go:136
# 0x57ce38 net.(*TCPListener).AcceptTCP+0x48 /usr/lib/go-1.10/src/net/tcpsock.go:246
# 0x66271e net/http.tcpKeepAliveListener.Accept+0x2e /usr/lib/go-1.10/src/net/http/server.go:3216
# 0x6614b4 net/http.(*Server).Serve+0x1a4 /usr/lib/go-1.10/src/net/http/server.go:2770
# 0x661208 net/http.(*Server).ListenAndServe+0xa8 /usr/lib/go-1.10/src/net/http/server.go:2711
# 0x662249 net/http.ListenAndServe+0x79 /usr/lib/go-1.10/src/net/http/server.go:2969
# 0x6d98ad main.main.func1+0x3d /home/hendrik/Dropbox/go/chat/server/server.go:83
1 @ 0x42e14a 0x42946a 0x428ae7 0x4d6f7b 0x4d6ffd 0x4d93f8 0x5646e2 0x57e85e 0x57d049 0x5e2bd7 0x6d973a 0x42dcf2 0x45ab71
# 0x428ae6 internal/poll.runtime_pollWait+0x56 /usr/lib/go-1.10/src/runtime/netpoll.go:173
# 0x4d6f7a internal/poll.(*pollDesc).wait+0x9a /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85
# 0x4d6ffc internal/poll.(*pollDesc).waitRead+0x3c /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90
# 0x4d93f7 internal/poll.(*FD).Accept+0x1a7 /usr/lib/go-1.10/src/internal/poll/fd_unix.go:372
# 0x5646e1 net.(*netFD).accept+0x41 /usr/lib/go-1.10/src/net/fd_unix.go:238
# 0x57e85d net.(*TCPListener).accept+0x2d /usr/lib/go-1.10/src/net/tcpsock_posix.go:136
# 0x57d048 net.(*TCPListener).Accept+0x48 /usr/lib/go-1.10/src/net/tcpsock.go:259
# 0x5e2bd6 crypto/tls.(*listener).Accept+0x36 /usr/lib/go-1.10/src/crypto/tls/tls.go:52
# 0x6d9739 main.main+0x2c9 /home/hendrik/Dropbox/go/chat/server/server.go:109
# 0x42dcf1 runtime.main+0x211 /usr/lib/go-1.10/src/runtime/proc.go:198
1 @ 0x42e14a 0x42e1fe 0x405f92 0x405c8b 0x6d9342 0x45ab71
# 0x6d9341 main.clientWriter+0x51 /home/hendrik/Dropbox/go/chat/server/server.go:73
1 @ 0x42e14a 0x43db50 0x6d8cb3 0x45ab71
# 0x6d8cb2 main.broadcaster+0x192 /home/hendrik/Dropbox/go/chat/server/server.go:25
1 @ 0x657e40 0x45ab71
# 0x657e40 net/http.(*connReader).backgroundRead+0x0 /usr/lib/go-1.10/src/net/http/server.go:667
1 @ 0x6d0408 0x6d0210 0x6ccd54 0x6d851d 0x6d88a1 0x65e444 0x6600b0 0x6610ec 0x65d461 0x45ab71
# 0x6d0407 runtime/pprof.writeRuntimeProfile+0x97 /usr/lib/go-1.10/src/runtime/pprof/pprof.go:679
# 0x6d020f runtime/pprof.writeGoroutine+0x9f /usr/lib/go-1.10/src/runtime/pprof/pprof.go:641
# 0x6ccd53 runtime/pprof.(*Profile).WriteTo+0x3e3 /usr/lib/go-1.10/src/runtime/pprof/pprof.go:310
# 0x6d851c net/http/pprof.handler.ServeHTTP+0x20c /usr/lib/go-1.10/src/net/http/pprof/pprof.go:243
# 0x6d88a0 net/http/pprof.Index+0x1d0 /usr/lib/go-1.10/src/net/http/pprof/pprof.go:254
# 0x65e443 net/http.HandlerFunc.ServeHTTP+0x43 /usr/lib/go-1.10/src/net/http/server.go:1947
# 0x6600af net/http.(*ServeMux).ServeHTTP+0x12f /usr/lib/go-1.10/src/net/http/server.go:2337
# 0x6610eb net/http.serverHandler.ServeHTTP+0xbb /usr/lib/go-1.10/src/net/http/server.go:2694
# 0x65d460 net/http.(*conn).serve+0x650 /usr/lib/go-1.10/src/net/http/server.go:1830
goroutine profile: total 7 - after first broadcast - not broadcasting any more
1 @ 0x42e14a 0x42946a 0x428ae7 0x4d6f7b 0x4d6ffd 0x4d7e5d 0x563dcf 0x574eda 0x5c5096 0x5c55a0 0x5c8b40 0x471196 0x471308 0x6d907d 0x45ab71
# 0x428ae6 internal/poll.runtime_pollWait+0x56 /usr/lib/go-1.10/src/runtime/netpoll.go:173
# 0x4d6f7a internal/poll.(*pollDesc).wait+0x9a /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85
# 0x4d6ffc internal/poll.(*pollDesc).waitRead+0x3c /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90
# 0x4d7e5c internal/poll.(*FD).Read+0x17c /usr/lib/go-1.10/src/internal/poll/fd_unix.go:157
# 0x563dce net.(*netFD).Read+0x4e /usr/lib/go-1.10/src/net/fd_unix.go:202
# 0x574ed9 net.(*conn).Read+0x69 /usr/lib/go-1.10/src/net/net.go:176
# 0x5c5095 crypto/tls.(*block).readFromUntil+0x95 /usr/lib/go-1.10/src/crypto/tls/conn.go:493
# 0x5c559f crypto/tls.(*Conn).readRecord+0xdf /usr/lib/go-1.10/src/crypto/tls/conn.go:595
# 0x5c8b3f crypto/tls.(*Conn).Read+0xff /usr/lib/go-1.10/src/crypto/tls/conn.go:1156
# 0x471195 io.ReadAtLeast+0x85 /usr/lib/go-1.10/src/io/io.go:309
# 0x471307 io.ReadFull+0x57 /usr/lib/go-1.10/src/io/io.go:327
# 0x6d907c main.handleConn+0x27c /home/hendrik/Dropbox/go/chat/server/server.go:52
1 @ 0x42e14a 0x42946a 0x428ae7 0x4d6f7b 0x4d6ffd 0x4d93f8 0x5646e2 0x57e85e 0x57ce39 0x66271f 0x6614b5 0x661209 0x66224a 0x6d98ae 0x45ab71
# 0x428ae6 internal/poll.runtime_pollWait+0x56 /usr/lib/go-1.10/src/runtime/netpoll.go:173
# 0x4d6f7a internal/poll.(*pollDesc).wait+0x9a /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85
# 0x4d6ffc internal/poll.(*pollDesc).waitRead+0x3c /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90
# 0x4d93f7 internal/poll.(*FD).Accept+0x1a7 /usr/lib/go-1.10/src/internal/poll/fd_unix.go:372
# 0x5646e1 net.(*netFD).accept+0x41 /usr/lib/go-1.10/src/net/fd_unix.go:238
# 0x57e85d net.(*TCPListener).accept+0x2d /usr/lib/go-1.10/src/net/tcpsock_posix.go:136
# 0x57ce38 net.(*TCPListener).AcceptTCP+0x48 /usr/lib/go-1.10/src/net/tcpsock.go:246
# 0x66271e net/http.tcpKeepAliveListener.Accept+0x2e /usr/lib/go-1.10/src/net/http/server.go:3216
# 0x6614b4 net/http.(*Server).Serve+0x1a4 /usr/lib/go-1.10/src/net/http/server.go:2770
# 0x661208 net/http.(*Server).ListenAndServe+0xa8 /usr/lib/go-1.10/src/net/http/server.go:2711
# 0x662249 net/http.ListenAndServe+0x79 /usr/lib/go-1.10/src/net/http/server.go:2969
# 0x6d98ad main.main.func1+0x3d /home/hendrik/Dropbox/go/chat/server/server.go:83
1 @ 0x42e14a 0x42946a 0x428ae7 0x4d6f7b 0x4d6ffd 0x4d93f8 0x5646e2 0x57e85e 0x57d049 0x5e2bd7 0x6d973a 0x42dcf2 0x45ab71
# 0x428ae6 internal/poll.runtime_pollWait+0x56 /usr/lib/go-1.10/src/runtime/netpoll.go:173
# 0x4d6f7a internal/poll.(*pollDesc).wait+0x9a /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:85
# 0x4d6ffc internal/poll.(*pollDesc).waitRead+0x3c /usr/lib/go-1.10/src/internal/poll/fd_poll_runtime.go:90
# 0x4d93f7 internal/poll.(*FD).Accept+0x1a7 /usr/lib/go-1.10/src/internal/poll/fd_unix.go:372
# 0x5646e1 net.(*netFD).accept+0x41 /usr/lib/go-1.10/src/net/fd_unix.go:238
# 0x57e85d net.(*TCPListener).accept+0x2d /usr/lib/go-1.10/src/net/tcpsock_posix.go:136
# 0x57d048 net.(*TCPListener).Accept+0x48 /usr/lib/go-1.10/src/net/tcpsock.go:259
# 0x5e2bd6 crypto/tls.(*listener).Accept+0x36 /usr/lib/go-1.10/src/crypto/tls/tls.go:52
# 0x6d9739 main.main+0x2c9 /home/hendrik/Dropbox/go/chat/server/server.go:109
# 0x42dcf1 runtime.main+0x211 /usr/lib/go-1.10/src/runtime/proc.go:198
1 @ 0x42e14a 0x42e1fe 0x405f92 0x405c8b 0x6d9342 0x45ab71
# 0x6d9341 main.clientWriter+0x51 /home/hendrik/Dropbox/go/chat/server/server.go:73
1 @ 0x42e14a 0x43db50 0x6d8cb3 0x45ab71
# 0x6d8cb2 main.broadcaster+0x192 /home/hendrik/Dropbox/go/chat/server/server.go:25
1 @ 0x4c3195 0x4c10df 0x4bfa29 0x4d7df8 0x563dcf 0x574eda 0x657e9a 0x45ab71
# 0x4c3194 syscall.Syscall+0x4 /usr/lib/go-1.10/src/syscall/asm_linux_amd64.s:18
# 0x4c10de syscall.read+0x5e /usr/lib/go-1.10/src/syscall/zsyscall_linux_amd64.go:749
# 0x4bfa28 syscall.Read+0x48 /usr/lib/go-1.10/src/syscall/syscall_unix.go:162
# 0x4d7df7 internal/poll.(*FD).Read+0x117 /usr/lib/go-1.10/src/internal/poll/fd_unix.go:153
# 0x563dce net.(*netFD).Read+0x4e /usr/lib/go-1.10/src/net/fd_unix.go:202
# 0x574ed9 net.(*conn).Read+0x69 /usr/lib/go-1.10/src/net/net.go:176
# 0x657e99 net/http.(*connReader).backgroundRead+0x59 /usr/lib/go-1.10/src/net/http/server.go:668
1 @ 0x6d0408 0x6d0210 0x6ccd54 0x6d851d 0x6d88a1 0x65e444 0x6600b0 0x6610ec 0x65d461 0x45ab71
# 0x6d0407 runtime/pprof.writeRuntimeProfile+0x97 /usr/lib/go-1.10/src/runtime/pprof/pprof.go:679
# 0x6d020f runtime/pprof.writeGoroutine+0x9f /usr/lib/go-1.10/src/runtime/pprof/pprof.go:641
# 0x6ccd53 runtime/pprof.(*Profile).WriteTo+0x3e3 /usr/lib/go-1.10/src/runtime/pprof/pprof.go:310
# 0x6d851c net/http/pprof.handler.ServeHTTP+0x20c /usr/lib/go-1.10/src/net/http/pprof/pprof.go:243
# 0x6d88a0 net/http/pprof.Index+0x1d0 /usr/lib/go-1.10/src/net/http/pprof/pprof.go:254
# 0x65e443 net/http.HandlerFunc.ServeHTTP+0x43 /usr/lib/go-1.10/src/net/http/server.go:1947
# 0x6600af net/http.(*ServeMux).ServeHTTP+0x12f /usr/lib/go-1.10/src/net/http/server.go:2337
# 0x6610eb net/http.serverHandler.ServeHTTP+0xbb /usr/lib/go-1.10/src/net/http/server.go:2694
# 0x65d460 net/http.(*conn).serve+0x650 /usr/lib/go-1.10/src/net/http/server.go:1830