Skip to content

WindowsFile: Retrieve correct Win32 error codes#3337

Merged
ashie merged 1 commit into
fluent:masterfrom
ashie:fix-incorrect-win32-last-error
Apr 20, 2021
Merged

WindowsFile: Retrieve correct Win32 error codes#3337
ashie merged 1 commit into
fluent:masterfrom
ashie:fix-incorrect-win32-last-error

Conversation

@ashie

@ashie ashie commented Apr 19, 2021

Copy link
Copy Markdown
Member

Which issue(s) this PR fixes:
none

What this PR does / why we need it:
WindowsFile calls GetLastError via win32-api to retrieve win32 error
code but the error code may be already reset by Ruby's internal code
so that it can't retrive a correct error code. Sometimes it causes
random unrecoverable errors when in_tail plugin tries to read a
non-existent file like the following:

  2021-04-14 03:15:45 +0000 [error]: #2 Fluent::Win32Error code: 158, The segment is already unlocked.: C:/path/to/log.txt

Fiddle or FFI has a method to avoid this issue:

We've added an equivalent method for win32-api:

This commit replaces the retrieving the error code with this method.

Docs Changes:
none

Release Note:
Same with the title.

@ashie ashie force-pushed the fix-incorrect-win32-last-error branch from 780f3b3 to 145be17 Compare April 19, 2021 06:56
WindowsFile calls GetLastError via win32-api to retrieve win32 error
code but the error code may be already reset by Ruby's internal code
so that it can't retrive a correct error code. Sometimes it causes
random unrecoverable errors when in_tail plugin tries to read a
non-existent file like the following:

  2021-04-14 03:15:45 +0000 [error]: #2 Fluent::Win32Error code: 158, The segment is already unlocked.: C:/path/to/log.txt

Fiddle or FFI has a method to avoid this issue:

  * Fiddle.win32_last_error
    https://ruby-doc.org/stdlib-3.0.0/libdoc/fiddle/rdoc/Fiddle.html#method-c-win32_last_error
  * FFI::LastError.winapi_error
    https://www.rubydoc.info/github/ffi/ffi/FFI/LastError#winapi_error-instance_method

We've added an equivalent method for win32-api:

  cosmo0920/win32-api#55

This commit replaces the retrieving the error code with this method.

Signed-off-by: Takuro Ashie <ashie@clear-code.com>
@ashie ashie force-pushed the fix-incorrect-win32-last-error branch from 145be17 to a51ee09 Compare April 19, 2021 07:20
@ashie ashie marked this pull request as ready for review April 19, 2021 09:00
@ashie ashie requested a review from cosmo0920 April 19, 2021 09:00

@cosmo0920 cosmo0920 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd confirmed that this patch can fix WindowsFile exceptions testing failures on Ruby 3.0 at current master(8c7d674).

At master(8c7d674):

  WindowsFile exceptions:
    test: ERROR_SHARING_VIOLATION raised:                                                               F
========================================================================================================================
Failure: test: ERROR_SHARING_VIOLATION raised(FileWrapperTest::WindowsFile exceptions)
./test/plugin/test_file_wrapper.rb:95:in `block (2 levels) in <class:FileWrapperTest>'
     92:         path = "#{TMP_DIR}/test_windows_file.txt"
     93:         file1 = file2 = nil
     94:         file1 = File.open(path, "wb")
  => 95:         assert_raise(Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, path)) do
     96:           file2 = Fluent::WindowsFile.new(path, 'r', FILE_SHARE_READ)
     97:         ensure
     98:           file2.close if file2

<#<Fluent::Win32Error: code: 32, The process cannot access the file because it is being used by another process. - ./test/plugin/../tmp/file_wrapper/test_windows_file.txt>> expected but was
<#<Fluent::Win32Error: code: 0, The operation completed successfully. - ./test/plugin/../tmp/file_wrapper/test_windows_file.txt>>

diff:
? #<Fluent::Win32Error: code: 32, The  p r   o  c    e    ss cannot access the file because it is being used by another process. - ./test/plugin/../tmp/file_wrapper/test_windows_file.txt>
?                             0       o e ati n  ompl ted  u                    u l

========================================================================================================================
: (0.029622)
    test: Errno::ENOENT raised:                                                                         F
========================================================================================================================
Failure: test: Errno::ENOENT raised(FileWrapperTest::WindowsFile exceptions)
./test/plugin/test_file_wrapper.rb:83:in `block (2 levels) in <class:FileWrapperTest>'
     80:     test 'Errno::ENOENT raised' do
     81:       path = "#{TMP_DIR}/nofile.txt"
     82:       file = nil
  => 83:       assert_raise(Errno::ENOENT) do
     84:         file = Fluent::WindowsFile.new(path)
     85:       ensure
     86:         file.close if file

<Errno::ENOENT> expected but was
<#<Fluent::Win32Error: code: 0, The operation completed successfully. - ./test/plugin/../tmp/file_wrapper/nofile.txt>>

diff:
?                Err                                                                                       no::ENOENT
? #<Fluent::Win32   or: code: 0, The operation completed successfully. - ./test/plugin/../tmp/file_wrapper/  file.txt>
========================================================================================================================
: (0.009904)
    test: nothing raised:                                                                               .: (0.002036)

With this patch:

  WindowsFile exceptions:
    test: ERROR_SHARING_VIOLATION raised:                                                               .: (0.001875)
    test: Errno::ENOENT raised:                                                                         .: (0.000978)
    test: nothing raised:

@cosmo0920

Copy link
Copy Markdown
Contributor

Other testing failures are caused by weird WSAGetLastError return codes.
We can merge this PR into master, I think. 👍

@fujimotos

fujimotos commented Apr 20, 2021

Copy link
Copy Markdown
Contributor

@ashie I have a vague uncomfortableness with this id_thread_data:

https://github.com/cosmo0920/win32-api/pull/55/files#diff-9a529c17bd767f1c607585ebc12ef9daaf94babeeb30a33ea6ff93f372f6dd58R70

Should not we assign some value to this variable? I felt that the variable was
waiting some initialization, but we forgot to do that.

@ashie

ashie commented Apr 20, 2021

Copy link
Copy Markdown
Member Author

Should not we assign some value to this variable? I felt that the variable was
waiting some initialization, but we didn't

Thank you for pointing out it.
I also worried about it after merging it, so I checked it.
Data_Make_Struct() calls xcalloc() so that it will be initialized by 0.
But I think it should be initialized manually to clarify the initial value.
In addition I have another worry thing, INT2NUM won't be suitable because DWORD is unsigned long.
I'll fix them and send another PR.

@fujimotos fujimotos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from the point above, I'm comfortable with this patch.

@ashie ashie merged commit a47183f into fluent:master Apr 20, 2021
@ashie ashie deleted the fix-incorrect-win32-last-error branch April 20, 2021 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants