Project

General

Profile

Bug #14713

<internal:prelude>:132:in `__write_nonblock': Protocol wrong type for socket (Errno::EPROTOTYPE)

Added by ioquatix (Samuel Williams) over 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:86690]

Description

Very occasionally on macOS, using Ruby 2.5.0, I get the above error.

Traceback (most recent call last):
    23: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-1.6.0/lib/async/task.rb:74:in `block in initialize'
    22: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/socket.rb:79:in `block in accept'
    21: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/socket.rb:46:in `block in accept_each'
    20: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/server.rb:51:in `accept'
    19: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/server.rb:51:in `catch'
    18: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/server.rb:52:in `block in accept'
    17: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/protocol/http1.rb:59:in `receive_requests'
    16: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/protocol/http11.rb:75:in `receive_requests'
    15: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/server.rb:54:in `block (2 levels) in accept'
    14: from /Users/samuel/Documents/socketry/falcon/lib/falcon/server.rb:33:in `handle_request'
    13: from /Users/samuel/Documents/socketry/falcon/lib/falcon/verbose.rb:46:in `call'
    12: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/middleware.rb:45:in `call'
    11: from /Users/samuel/Documents/socketry/falcon/lib/falcon/proxy.rb:71:in `call'
    10: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/client.rb:65:in `call'
     9: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/protocol/http11.rb:98:in `call'
     8: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-http-0.20.0/lib/async/http/protocol/http11.rb:112:in `write_request'
     7: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/stream.rb:76:in `flush'
     6: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/stream.rb:175:in `syswrite'
     5: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/generic.rb:47:in `block in wrap_blocking_method'
     4: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/generic.rb:124:in `async_send'
     3: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/generic.rb:131:in `async'
     2: from /Users/samuel/.rvm/gems/ruby-2.5.0/gems/async-io-1.7.0/lib/async/io/generic.rb:125:in `block in async_send'
     1: from <internal:prelude>:132:in `write_nonblock'

I'm not even sure how it's possible to receive this message in write_nonblock since by that point the socket is well and truely setup. Maybe a bug in the OS?

I'm not sure how to reproduce, I've only seen it once a month and I don't have any strategy to reproduce yet. I could try a busy loop.


Related issues

Related to Ruby master - Bug #12914: FTPTest#test_list_read_timeout_exceeded causes EPROTOTYPE on Mac OS X 10.10ClosedActions

Associated revisions

Revision 7727b22e
Added by nobu (Nobuyoshi Nakada) over 1 year ago

io.c: workaround for EPROTOTYPE

  • io.c (internal_write_func, internal_writev_func): retry at
    unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
    [ruby-core:86690] [Bug #14713]

  • ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63304 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 63304
Added by nobu (Nobuyoshi Nakada) over 1 year ago

io.c: workaround for EPROTOTYPE

  • io.c (internal_write_func, internal_writev_func): retry at
    unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
    [ruby-core:86690] [Bug #14713]

  • ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.

Revision 63304
Added by nobu (Nobuyoshi Nakada) over 1 year ago

io.c: workaround for EPROTOTYPE

  • io.c (internal_write_func, internal_writev_func): retry at
    unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
    [ruby-core:86690] [Bug #14713]

  • ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.

Revision fcb4a3d8
Added by nagachika (Tomoyuki Chikanaga) about 1 year ago

merge revision(s) 63304: [Backport #14713]

    io.c: workaround for EPROTOTYPE

    * io.c (internal_write_func, internal_writev_func): retry at
      unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
      [ruby-core:86690] [Bug #14713]

    * ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@63826 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 63826
Added by nagachika (Tomoyuki Chikanaga) about 1 year ago

merge revision(s) 63304: [Backport #14713]

io.c: workaround for EPROTOTYPE

* io.c (internal_write_func, internal_writev_func): retry at
  unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
  [ruby-core:86690] [Bug #14713]

* ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.

History

Updated by nobu (Nobuyoshi Nakada) over 1 year ago

ioquatix (Samuel Williams) wrote:

Very occasionally on macOS, using Ruby 2.5.0, I get the above error.

It happens often on macOS.

I'm not even sure how it's possible to receive this message in write_nonblock since by that point the socket is well and truely setup. Maybe a bug in the OS?

Probably, but not sure.

Updated by ioquatix (Samuel Williams) over 1 year ago

It happens often on macOS.

I don't have this experience. I can't systematically reproduce the issue. It only happens perhaps once a month even thought I'm running networking code almost daily on macOS, and these are code paths that do occasionally show the issue..

It would be nice to figure out a busy loop that can reproduce the issue on demand, even if it takes a few minutes.

I'm running on macOS 10.13.4

Updated by ioquatix (Samuel Williams) over 1 year ago

I tried digging into this issue.

I found some other people with similar problems: https://github.com/nodejs/node/issues/2382

The most interesting article digging into the issue: http://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/

I'm still digesting this information.

Updated by ioquatix (Samuel Williams) over 1 year ago

It seems that in this specific case, EPROTOTYPE is the same as EPIPE. It's a bug in the kernel code. I wonder if we should compensate for it by detecting EPROTOTYPE by write, and raising EPIPE.

#5

Updated by nobu (Nobuyoshi Nakada) over 1 year ago

  • Related to Bug #12914: FTPTest#test_list_read_timeout_exceeded causes EPROTOTYPE on Mac OS X 10.10 added

Updated by ioquatix (Samuel Williams) over 1 year ago

I've made a PR which fixes the issue.

https://github.com/ruby/ruby/pull/1868

I believe it would make sense to back-port it.

Additionally the following change could be reverted: https://bugs.ruby-lang.org/issues/12914

Updated by ioquatix (Samuel Williams) over 1 year ago

I made a patch for write_nonblock. But this probably equally applies to send, sendmsg, etc. Perhaps we can discuss the right course of action to cover all these cases.

#8

Updated by nobu (Nobuyoshi Nakada) over 1 year ago

  • Status changed from Open to Closed

Applied in changeset trunk|r63304.


io.c: workaround for EPROTOTYPE

  • io.c (internal_write_func, internal_writev_func): retry at
    unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
    [ruby-core:86690] [Bug #14713]

  • ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.

Updated by ioquatix (Samuel Williams) over 1 year ago

Thanks for solving this problem. Your patch was much more thorough.

Any change to back port this?

#10

Updated by nobu (Nobuyoshi Nakada) over 1 year ago

  • Backport changed from 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN to 2.3: REQUIRED, 2.4: REQUIRED, 2.5: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) about 1 year ago

  • Backport changed from 2.3: REQUIRED, 2.4: REQUIRED, 2.5: REQUIRED to 2.3: REQUIRED, 2.4: REQUIRED, 2.5: DONE

ruby_2_5 r63826 merged revision(s) 63304.

Also available in: Atom PDF