-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
x/mobile/bind: ios app crashes with SIGPIPE in background #17393
Comments
Actually, it may be that lldb is intercepting the SIGPIPE itself. One workaround would be to create the socket with SO_NOSIGPIPE. |
So I have implemented a For future somebody who runs into this problem, here is some code: // SilenceSIGPIPE configures the net.Conn in a way that silences SIGPIPEs with
// the SO_NOSIGPIPE socket option.
func SilenceSIGPIPE(c net.Conn) error {
// use reflection until https://github.com/golang/go/issues/9661 is fixed
fd := int(reflect.ValueOf(c).Elem().FieldByName("fd").Elem().FieldByName("sysfd").Int())
return syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_NOSIGPIPE, 1)
}
// NoSIGPIPEDialer returns a dialer that won't SIGPIPE should a connection
// actually SIGPIPE. This prevents the debugger from intercepting the signal
// even though this is normal behaviour.
type NoSIGPIPEDialer net.Dialer
func (d *NoSIGPIPEDialer) handle(c net.Conn, err error) (net.Conn, error) {
if err != nil {
return nil, err
}
if err := SilenceSIGPIPE(c); err != nil {
c.Close()
return nil, err
}
return c, err
}
func (d *NoSIGPIPEDialer) Dial(network, address string) (net.Conn, error) {
c, err := (*net.Dialer)(d).Dial(network, address)
return d.handle(c, err)
}
func (d *NoSIGPIPEDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
c, err := (*net.Dialer)(d).DialContext(ctx, network, address)
return d.handle(c, err)
} And // NoSIGPIPETransport is a default HTTP transport (configured in the same manner)
var NoSIGPIPETransport http.RoundTripper = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&NoSIGPIPEDialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
func init() {
// Install NoSIGPIPETransport as the default HTTP transport
http.DefaultTransport = NoSIGPIPETransport
} |
Also, this codes needs reflection until #9661 is fixed. |
CL https://golang.org/cl/32796 mentions this issue. |
Thanks @eliasnaur ! Another workaround in the mean time is: func init() {
// Install NoSIGPIPEDialer as the default HTTP dialer
defaultTransport := http.DefaultTransport.(*http.Transport)
defaultTransport.DialContext = (&NoSIGPIPEDialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext
} |
CL 32796 was reverted (see #18100 for details) so the SIGPIPE fix will not be in Go 1.8. An easy workaround is to call |
Thank you the information. We are still running our NoSIGPIPEDialer anyhow. |
I've added a workaround in Gomobile so you shouldn't need your NoSIGPIPEDialer anymore: https://go-review.googlesource.com/c/33771/ |
Reopening per #18100 (comment) |
CL https://golang.org/cl/35960 mentions this issue. |
What version of Go are you using (
go version
)?go version devel +56d35d4 Sun Oct 9 00:22:59 2016 +0000 darwin/amd64
gomobile version +6ea0bb5 Wed Oct 5 13:16:13 2016 +0000 (android,ios); androidSDK=
What operating system and processor architecture are you using (
go env
)?What did you do?
App is attached to XCode's lldb.
Try to wake an app with a gomobile bind binary makes it crash when the device was locked for too long. Usually after ~2 minutes.
I can reproduce it if I make a HTTP call to Internet.
Strangely enough, this seems not to occur when trying to get the raw IP address.
What did you expect to see?
Program resume normally.
What did you see instead?
Program crashes with the following stack traces:
The text was updated successfully, but these errors were encountered: