Skip to content

depau/golang-unix-websocket-deadlock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Golang unix domain socket WebSocket deadlock reproducer

This is a reproducer for a deadlock that happens when using a WebSocket server over a Unix domain socket in Golang.

How to reproduce

Build both the client and the server:

go build -C ./cmd/server
go build -C ./cmd/client

Run the server:

./cmd/server/server /tmp/wsunix.sock

Run the client:

./cmd/client/client /tmp/wsunix.sock

Re-run the client until the server freezes when upgrading to WebSocket.

Both the client and the server use Gorilla WebSocket, although I additionally implemented a simple WebSocket to demonstrate that the issue is likely not caused by Gorilla WebSocket.

To run the server without Gorilla WebSocket, use the --no-gorilla flag:

./cmd/server/server /tmp/wsunix.sock --no-gorilla

In this mode it will occasionally freeze when hijacking the connection.

The culprit seems to be this stack trace where net/http.(*conn).hijackLocked tries to abort the background read goroutine but the goroutine's syscall is never interrupted:

1 @ 0x46fbce 0x471199 0x471179 0x47f725 0x6404c5 0x63edef 0x646a77 0x63d314 0x680e92 0x6521ce 0x645890 0x477b41
#       0x471178        sync.runtime_notifyListWait+0x138               /usr/lib/go/src/runtime/sema.go:587
#       0x47f724        sync.(*Cond).Wait+0x84                          /usr/lib/go/src/sync/cond.go:71
#       0x6404c4        net/http.(*connReader).abortPendingRead+0xa4    /usr/lib/go/src/net/http/server.go:738
#       0x63edee        net/http.(*conn).hijackLocked+0x2e              /usr/lib/go/src/net/http/server.go:321
#       0x646a76        net/http.(*response).Hijack+0xd6                /usr/lib/go/src/net/http/server.go:2170
#       0x63d313        net/http.(*ResponseController).Hijack+0x193     /usr/lib/go/src/net/http/responsecontroller.go:71
#       0x680e91        main.(*server).ServeHTTP+0x991                  /home/davide.depau/Projects/unix-socket-ws-hang/cmd/server/main.go:167
#       0x6521cd        net/http.serverHandler.ServeHTTP+0x8d           /usr/lib/go/src/net/http/server.go:3210
#       0x64588f        net/http.(*conn).serve+0x5cf                    /usr/lib/go/src/net/http/server.go:2092

Either I'm opening the Unix socket with the wrong (default) flags or there's a bug in the Go standard library.

About

Demonstration code for an issue with the Golang stdlib

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages