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

Unexpected error code with WSAGetLastError even though the previous function calll was failed #72

Closed
kenhys opened this issue Mar 26, 2021 · 4 comments

Comments

@kenhys
Copy link

kenhys commented Mar 26, 2021

The problem

There is a case that fiddle fails to get error code with WSAGetLastEror on Win32.

This problem is observed with Ruby 3.0 only.

Expected result

WSAGetLastError returns correct error code when previous function call was failed.

Actual result

WSAGetLastError returns 0 even thought when previous function call was failed.

  • Windows 10 20H2 (19042.870)
  • Ruby installer with fiddle 1.0.7

How to reproduce

Here is the sample code (test-wsagetlasterror.rb) to reproduce issue.

module WinSock
  require 'fiddle/import'
  extend Fiddle::Importer
  dlload 'ws2_32.dll'
  extern 'int bind(int, void *, int)'
  extern 'int WSAGetLastError(void)'
end

p WinSock.bind(0, nil, 0)
p WinSock.WSAGetLastError

When using with Ruby 2.7 https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.7.2-1/rubyinstaller-2.7.2-1-x64.exe
WinSock.WSAGetLastError returns 10038 (expected)

PS C:\work\fluentd> ridk use
1 - C:/Ruby25-x64       ruby 2.5.8p224 (2020-03-31 revision 67882) [x64-mingw32]
2 - C:/Ruby26-x64       ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]
3 - C:/Ruby27-x64       ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x64-mingw32]
4 - C:/Ruby30-x64       ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]
Select ruby version to enable: 3
Disable C:/Ruby26-x64
Disable C:/Ruby30-x64
Enable C:/Ruby27-x64
PS C:\work\fluentd> ruby .\test-wsagetlasterror.rb
-1
10038

When using with Ruby 3.0 https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-3.0.0-1/rubyinstaller-3.0.0-1-x64.exe,
WinSock.WSAGetLastError returns 0 (not expected)

PS C:\work\fluentd> ridk use
1 - C:/Ruby25-x64       ruby 2.5.8p224 (2020-03-31 revision 67882) [x64-mingw32]
2 - C:/Ruby26-x64       ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]
3 - C:/Ruby27-x64       ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x64-mingw32]
4 - C:/Ruby30-x64       ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]
Select ruby version to enable: 4
Disable C:/Ruby26-x64
Disable C:/Ruby27-x64
Enable C:/Ruby30-x64
PS C:\work\fluentd> ruby .\test-wsagetlasterror.rb
-1
0
kenhys added a commit to kenhys/fluentd that referenced this issue Mar 31, 2021
It should be fixed in Fiddle

ref. ruby/fiddle#72

Signed-off-by: Kentaro Hayashi <hayashi@clear-code.com>
@kou
Copy link
Member

kou commented Apr 13, 2021

It seems that Ruby 3.0's rb_funcall() resets the latest socket error information internally. (select()?)

So calling WSAGetLastError() manually by Fiddle isn't portable. How about adding Fiddle.win32_last_socket_error like existing Fiddle.win32_error and using it instead of calling WSAGetLastError()?

@kenhys
Copy link
Author

kenhys commented Apr 13, 2021

Thanks, I'll try that way.

@kou
Copy link
Member

kou commented Apr 13, 2021

What are you trying to do? Opening a PR?

@kou kou closed this as completed in 76158db Apr 19, 2021
@kou
Copy link
Member

kou commented Apr 19, 2021

I've implemented them and released a new version.

Could you report this to https://bugs.ruby-lang.org/ ? Resetting the last socket error may be a bug of Ruby 3.0.

ashie added a commit to ashie/serverengine that referenced this issue Apr 21, 2021
On Ruby 3.0, calling WSAGetLastError from Ruby script cannot get a
correct error code because Ruby's internal code resets it. Use
`Fiddle.win32_last_socket_error` instead if it's availbale.
You need fiddle 1.0.8 or later to use it. In addition, when you use
RubyInstaller, you need to specify the path of fiddle by `RUBYLIB` or
`ruby -I` at this moment because it loads Ruby's bundled fiddle before
initializing gem. This is the why we don't add a dependency to fiddle,
just only installing fiddle doesn't take effect.

e.g.)

  > gem install fiddle --version 1.0.8
  > set RUBYLIB=C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/fiddle-1.0.8/lib
  > bundle exec rake spec

See also:
* ruby/fiddle#72
* https://bugs.ruby-lang.org/issues/17813
* https://github.com/oneclick/rubyinstaller2/blob/8225034c22152d8195bc0aabc42a956c79d6c712/lib/ruby_installer/build/dll_directory.rb

Signed-off-by: Takuro Ashie <ashie@clear-code.com>
ashie added a commit to ashie/serverengine that referenced this issue Apr 27, 2021
On Ruby 3.0, calling WSAGetLastError from Ruby script cannot get a
correct error code because Ruby's internal code resets it. Use
`Fiddle.win32_last_socket_error` instead if it's availbale.
You need fiddle 1.0.8 or later to use it. In addition, when you use
RubyInstaller, you need to specify the path of fiddle by `RUBYLIB` or
`ruby -I` at this moment because it loads Ruby's bundled fiddle before
initializing gem. This is the why we don't add a dependency to fiddle,
just only installing fiddle doesn't take effect.

e.g.)

  > gem install fiddle --version 1.0.8
  > set RUBYLIB=C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/fiddle-1.0.8/lib
  > bundle exec rake spec

See also:
* ruby/fiddle#72
* https://bugs.ruby-lang.org/issues/17813
* https://github.com/oneclick/rubyinstaller2/blob/8225034c22152d8195bc0aabc42a956c79d6c712/lib/ruby_installer/build/dll_directory.rb

Signed-off-by: Takuro Ashie <ashie@clear-code.com>
ashie added a commit to ashie/fluentd that referenced this issue May 25, 2021
On Ruby 3.0, we need to use fiddle 1.0.8 or later to retrieve correct
error code. In addition, we have to specify the path of fiddle by RUBYLIB
because RubyInstaller loads Ruby's bundled fiddle before initializing gem.
See also:
* ruby/fiddle#72
* https://bugs.ruby-lang.org/issues/17813
* https://github.com/oneclick/rubyinstaller2/blob/8225034c22152d8195bc0aabc42a956c79d6c712/lib/ruby_installer/build/dll_directory.rb

Fix fluent#3263

Signed-off-by: Takuro Ashie <ashie@clear-code.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants