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: SIGPIPE using unix domain socket #44177

Open
helios741 opened this issue Feb 9, 2021 · 2 comments
Open

net: SIGPIPE using unix domain socket #44177

helios741 opened this issue Feb 9, 2021 · 2 comments

Comments

@helios741
Copy link

@helios741 helios741 commented Feb 9, 2021

What version of Go are you using (go version)?

# go version
go version go1.13.9 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
# go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go-1.13"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go-1.13/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build098414746=/tmp/go-build -gno-record-gcc-switches"

What did you do?

linux version:

# uname -a
Linux iZ8vbaym9jmge8qd5hlcpiZ 4.15.0-111-generic #112-Ubuntu SMP Thu Jul 9 20:32:34 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

i have go program:

go http server Output
package main

import (
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
_ "net/http/pprof"
)

func main() {

h2 := func(w http.ResponseWriter, _ *http.Request) {
time.Sleep(2 * time.Second)
fmt.Println("555555")
if _, err := w.Write(make([]byte, 9999)); err != nil {
fmt.Println("---=====: ", err.Error(), syscall.EPIPE == err)
return
}
}
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
http.HandleFunc("/endpoint", h2)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGPIPE)
go func() {
sig := <-sigs
fmt.Println("6666666666", sig.String())
fmt.Println(sig)
}()
log.Fatal(http.ListenAndServe(":8888", nil))
}

I requested the following two ways and got the following different results:

1、 by unix domain socket

curl request curl 127.0.0.1:8888/endpoint -m 0.2
result:

555555
---=====:  write tcp 127.0.0.1:8888->127.0.0.1:33794: write: broken pipe false
6666666666 broken pipe
broken pipe

2、 by tcp socket

curl request: curl 47.92.3.20:8888/endpoint -m 0.2
get result: 555555

The debug I did has the following

1、 strace
unix domain socket( curl 127.0.0.1:8888/endpoint -m 0.2)

strace -f -v -p 1631 Output
 
[pid  1634] <... epoll_pwait resumed> [{EPOLLIN, {u32=1450127112, u64=140013089009416}}], 128, -1, NULL, 0) = 1
[pid  1634] futex(0xb37590, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1632] <... restart_syscall resumed> ) = 0
[pid  1634] accept4(3,  
[pid  1632] nanosleep({tv_sec=0, tv_nsec=20000},  
[pid  1634] <... accept4 resumed> {sa_family=AF_INET6, sin6_port=htons(35068), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [112->28], SOCK_CLOEXEC|SOCK_NONBLOCK) = 7
[pid  1634] epoll_ctl(5, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=1450126488, u64=140013089008792}}) = 0
[pid  1634] getsockname(7, {sa_family=AF_INET6, sin6_port=htons(8888), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [112->28]) = 0
[pid  1634] setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0
[pid  1634] setsockopt(7, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
[pid  1634] setsockopt(7, SOL_TCP, TCP_KEEPINTVL, [15], 4) = 0
[pid  1634] setsockopt(7, SOL_TCP, TCP_KEEPIDLE, [15], 4) = 0
[pid  1634] accept4(3, 0xc0000c79f8, [112], SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable)
[pid  1634] read(7, 0xc000102000, 4096) = -1 EAGAIN (Resource temporarily unavailable)
[pid  1634] epoll_pwait(5, [{EPOLLOUT, {u32=1450126488, u64=140013089008792}}], 128, 0, NULL, 0) = 1
[pid  1634] epoll_pwait(5, [{EPOLLIN|EPOLLOUT, {u32=1450126488, u64=140013089008792}}], 128, -1, NULL, 0) = 1
[pid  1634] read(7, "GET /endpoint HTTP/1.1\r\nHost: 12"..., 4096) = 86
[pid  1634] futex(0xc0000aa4c8, FUTEX_WAKE_PRIVATE, 1 
[pid  1636] <... futex resumed> )       = 0
[pid  1634] <... futex resumed> )       = 1
[pid  1636] read(7,  
[pid  1634] futex(0xb3b460, FUTEX_WAIT_PRIVATE, 0, {tv_sec=1, tv_nsec=999998359} 
[pid  1636] <... read resumed> 0xc000100161, 1) = -1 EAGAIN (Resource temporarily unavailable)
[pid  1636] epoll_pwait(5, [], 128, 0, NULL, 0) = 0
[pid  1636] epoll_pwait(5,  
[pid  1632] <... nanosleep resumed> NULL) = 0
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} 
[pid  1636] <... epoll_pwait resumed> [{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=1450126488, u64=140013089008792}}], 128, -1, NULL, 0) = 1
[pid  1636] futex(0xb37590, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1632] <... futex resumed> )       = 0
[pid  1636] read(7,  
[pid  1632] sched_yield( 
[pid  1636] <... read resumed> "", 1)   = 0
[pid  1636] epoll_pwait(5, [], 128, 0, NULL, 0) = 0
[pid  1636] epoll_pwait(5,  
[pid  1632] <... sched_yield resumed> ) = 0
[pid  1632] futex(0xb37490, FUTEX_WAKE_PRIVATE, 1) = 0
[pid  1632] nanosleep({tv_sec=0, tv_nsec=20000}, NULL) = 0
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} 
[pid  1634] <... futex resumed> )       = -1 ETIMEDOUT (Connection timed out)
[pid  1634] futex(0xb37590, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1632] <... futex resumed> )       = 0
[pid  1634] write(1, "555555\n", 7 
[pid  1632] sched_yield( 
[pid  1634] <... write resumed> )       = 7
[pid  1634] write(7, "HTTP/1.1 200 OK\r\nDate: Tue, 09 F"..., 4096 
[pid  1636] <... epoll_pwait resumed> [{EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=1450126488, u64=140013089008792}}], 128, -1, NULL, 0) = 1
[pid  1634] <... write resumed> )       = 4096
[pid  1636] epoll_pwait(5,  
[pid  1634] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 6033) = -1 EPIPE (Broken pipe)
[pid  1634] --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=1631, si_uid=0} ---
[pid  1634] futex(0xb540a0, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1633] <... futex resumed> )       = 0
[pid  1634] rt_sigreturn({mask=[]} 
[pid  1633] futex(0xc000036848, FUTEX_WAIT_PRIVATE, 0, NULL 
[pid  1634] <... rt_sigreturn resumed> ) = -1 EPIPE (Broken pipe)
[pid  1634] epoll_ctl(5, EPOLL_CTL_DEL, 7, 0xc0000467bc) = 0
[pid  1634] close(7)                    = 0
[pid  1634] write(1, "---=====:  write tcp 127.0.0.1:8"..., 79) = 79
[pid  1634] futex(0xc000036848, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1633] <... futex resumed> )       = 0
[pid  1634] futex(0xb540a0, FUTEX_WAIT_PRIVATE, 0, NULL 
[pid  1633] futex(0xc000036848, FUTEX_WAIT_PRIVATE, 0, NULL 
[pid  1632] <... sched_yield resumed> ) = 0
[pid  1632] futex(0xb37490, FUTEX_WAKE_PRIVATE, 1) = 0
[pid  1632] nanosleep({tv_sec=0, tv_nsec=20000}, NULL) = 0
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
[pid  1632] --- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
[pid  1632] rt_sigreturn({mask=[]})     = -1 EINTR (Interrupted system call)
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=54, tv_nsec=43543031}
Please pay attention to **Broken pipe**

tcp socket( curl 47.92.3.20:8888/endpoint -m 0.)

strace -f -v -p 1631 Output
pid  1636] <... epoll_pwait resumed> [{EPOLLIN, {u32=1450127112, u64=140013089009416}}], 128, -1, NULL, 0) = 1
[pid  1636] futex(0xb37590, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1632] <... futex resumed> )       = 0
[pid  1636] accept4(3,  
[pid  1632] nanosleep({tv_sec=0, tv_nsec=20000},  
[pid  1636] <... accept4 resumed> {sa_family=AF_INET6, sin6_port=htons(51136), inet_pton(AF_INET6, "::ffff:47.92.3.20", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [112->28], SOCK_CLOEXEC|SOCK_NONBLOCK) = 7
[pid  1636] epoll_ctl(5, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=1450126488, u64=140013089008792}}) = 0
[pid  1636] getsockname(7, {sa_family=AF_INET6, sin6_port=htons(8888), inet_pton(AF_INET6, "::ffff:172.28.130.126", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [112->28]) = 0
[pid  1636] setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0
[pid  1636] setsockopt(7, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
[pid  1636] setsockopt(7, SOL_TCP, TCP_KEEPINTVL, [15], 4) = 0
[pid  1636] setsockopt(7, SOL_TCP, TCP_KEEPIDLE, [15], 4) = 0
[pid  1636] accept4(3, 0xc0000c79f8, [112], SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable)
[pid  1636] read(7, "GET /endpoint HTTP/1.1\r\nHost: 47"..., 4096) = 87
[pid  1636] futex(0xc000036848, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1633] <... futex resumed> )       = 0
[pid  1636] futex(0xb3b460, FUTEX_WAIT_PRIVATE, 0, {tv_sec=1, tv_nsec=999998097} 
[pid  1633] read(7, 0xc0001002e1, 1)    = -1 EAGAIN (Resource temporarily unavailable)
[pid  1633] epoll_pwait(5, [{EPOLLOUT, {u32=1450126488, u64=140013089008792}}], 128, 0, NULL, 0) = 1
[pid  1633] epoll_pwait(5,  
[pid  1632] <... nanosleep resumed> NULL) = 0
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} 
[pid  1633] <... epoll_pwait resumed> [{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=1450126488, u64=140013089008792}}], 128, -1, NULL, 0) = 1
[pid  1633] futex(0xb37590, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1632] <... futex resumed> )       = 0
[pid  1633] read(7,  
[pid  1632] sched_yield( 
[pid  1633] <... read resumed> "", 1)   = 0
[pid  1633] epoll_pwait(5, [], 128, 0, NULL, 0) = 0
[pid  1633] epoll_pwait(5,  
[pid  1632] <... sched_yield resumed> ) = 0
[pid  1632] futex(0xb37490, FUTEX_WAKE_PRIVATE, 1) = 0
[pid  1632] nanosleep({tv_sec=0, tv_nsec=20000}, NULL) = 0
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0} 
[pid  1636] <... futex resumed> )       = -1 ETIMEDOUT (Connection timed out)
[pid  1636] futex(0xb37590, FUTEX_WAKE_PRIVATE, 1) = 1
[pid  1632] <... futex resumed> )       = 0
[pid  1636] write(1, "555555\n", 7 
[pid  1632] sched_yield( 
[pid  1636] <... write resumed> )       = 7
[pid  1636] write(7, "HTTP/1.1 200 OK\r\nDate: Tue, 09 F"..., 4096) = 4096
[pid  1636] write(7, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 6033) = 6033
[pid  1636] write(7, "\r\n0\r\n\r\n", 7) = 7
[pid  1636] read(7, "", 4096)           = 0
[pid  1636] futex(0xc0000aa4c8, FUTEX_WAIT_PRIVATE, 0, NULL 
[pid  1632] <... sched_yield resumed> ) = 0
[pid  1633] <... epoll_pwait resumed> [{EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=1450126488, u64=140013089008792}}], 128, -1, NULL, 0) = 1
[pid  1632] futex(0xb37490, FUTEX_WAKE_PRIVATE, 1 
[pid  1633] epoll_pwait(5,  
[pid  1632] <... futex resumed> )       = 0
[pid  1632] nanosleep({tv_sec=0, tv_nsec=20000}, NULL) = 0
[pid  1632] futex(0xb37590, FUTEX_WAIT_PRIVATE, 0, {tv_sec=60, tv_nsec=0}

no broken pipe

What did you expect to see?

I want to get the same result through unix domain socket and tcp socket.

What did you see instead?

Does go's netpoll handle unix domain socket and tcp socket in different ways? I don’t see the difference in netpoll code.

@helios741 helios741 changed the title Broken pipe appears when accessing http service through unix domain socket Broken pipe appears when request http service through unix domain socket Feb 9, 2021
@seankhliao
Copy link
Contributor

@seankhliao seankhliao commented Feb 9, 2021

A broken pipe is expected since it's closed by curl, this is most likely masked by OS buffering when you go over the network

@seankhliao seankhliao changed the title Broken pipe appears when request http service through unix domain socket net: SIGPIPE using unix domain socket Feb 9, 2021
@helios741
Copy link
Author

@helios741 helios741 commented Feb 12, 2021

@seankhliao Why doesn't OS buffering appear broken pipe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants