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

Save and restore GetLastError() on Windows. #62

Merged
merged 3 commits into from
Aug 8, 2021

Conversation

fstromback
Copy link
Contributor

This is a patch for the problem outlined in issue #61 - that the value in
GetLastError() is not automatically saved and restored when a vectored exception
handler is called. This is solved the same way as errno was handled on POSIX
systems.

This patch does not save and restore errno on Windows, since it seems like the
MPS does not call any functions that modify errno on the critical path on
Windows (generally only functions from POSIX do that).

I have tried to update the documentation similar to what was done for the errno
patch for POSIX, but as I am not entirely familiar with the RST format, I may have
made some mistakes there.

@fstromback
Copy link
Contributor Author

I should mention: I have tried building and running this on Windows (using the hot variety). I have not run it against the tests in tests/, but it works well when I run it with my language that uses the MPS (so at least it passes the smoke-test).

Copy link
Member

@gareth-rees gareth-rees left a comment

Choose a reason for hiding this comment

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

Thanks for sending the pull request, which looks good. I've made a couple of comments, but we also need some test coverage. If you look at #32 you'll see that I did this by updating test/function/236.c, which was convenient because this test was already exercising thread suspend and restore on POSIX platforms. In your case you'll want to write a new test case, which will mean figuring out how to use the test system! There are some slender usage notes in test/README, otherwise ask if you need help.

code/misc.h Outdated Show resolved Hide resolved
code/protw3.c Outdated Show resolved Hide resolved
This is to illustrate that the value in GetLastError() may be
clobbered by the exception handler on Windows in some
circumstances. As this commit is before the patch, the test currently
fails (clearly showing the issue).
@fstromback
Copy link
Contributor Author

I have updated the branch now as suggested above.

I have also added a test case for this (in 237.c). I put that in its own commit now, so it is easy to see that the test fails consistently on Windows first, then when the fix is applied, it passes consistently.

It was a bit tricky to get the right conditions for the issue to be visible. The test is written so that it does its best to set up everything, verify that the right conditions are met and then do the test. This way it can reliably determine that it tests the right thing, and can fail if it for some reasons fails to set up the right conditions (the MPS must decide to raise both the read and write barrier somewhere, so we can trigger a scan in the vectored exception handler).

I have described in quite a bit of detail how it works inside the test file. Hopefully this is understandable.

code/protw3.c Outdated
* GetLastError() and SetLastError() are defined.
*/

#define LAST_ERROR_SAVE BEGIN DWORD _saved_last_error = GetLastError(); BEGIN
Copy link
Member

Choose a reason for hiding this comment

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

Why use macros?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used the ERRNO_SAVE and ERRNO_RESTORE as a template here initially. But since it is only used in one location at the moment I agree that the macro-free version is better. I will fix that.

MPS does not cause system calls in the mutator to update the value
returned from ``GetLastError()`` when the exception handler is called
due to a fault. This may cause the MPS to destroy the previous value
there.
Copy link
Member

Choose a reason for hiding this comment

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

link to issue 61.

* the MPS will call a system call that fails in the exception handler
* when responding to the hit.
*
* The tool we use here is a separate thread. We create and register
Copy link
Member

Choose a reason for hiding this comment

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

This is massively cunning. Applause!

Copy link
Member

@NickBarnes NickBarnes left a comment

Choose a reason for hiding this comment

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

Looks OK to me. I'd prefer to have straight calls to GetLastError and SetLastError, rather than macros.

This is a patch for the problem outlined in issue Ravenbrook#61 - that the value in
GetLastError() is not automatically saved and restored when a vectored exception
handler is called. This is solved the same way as errno was handled on POSIX
systems.

This patch does *not* save and restore errno on Windows, since it seems like the
MPS does not call any functions that modify errno on the critical path on
Windows (generally only functions from POSIX do that).
@fstromback
Copy link
Contributor Author

Thank you for your feedback @NickBarnes ! I have made the suggested changes (removed the macros and added the link in the documentation).

@gareth-rees gareth-rees linked an issue May 28, 2021 that may be closed by this pull request
@fstromback
Copy link
Contributor Author

Hi again,

I just wanted to check in on the status of this PR. I think I have made all requested changes, but I might have missed something (either in the code or regarding licences etc.). If so, please let me know!

Copy link
Member

@gareth-rees gareth-rees left a comment

Choose a reason for hiding this comment

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

Sorry for being so dilatory in getting this merged. I've been putting it off because we no longer have any continuous integration coverage on Windows. (This used to live in a Jenkins instance in the Ravenbrook office, but that was taken offline when the office was closed and no-one has had the spoons to get it going again.) But the continuous integration situation is not going to get better by doing nothing, so I recommend merging as-is (or with the typo fixes below) and worrying about the Windows build at the point when (or if) someone is able to get continuous integration going again.

test/function/237.c Outdated Show resolved Hide resolved
test/function/237.c Outdated Show resolved Hide resolved
@fstromback
Copy link
Contributor Author

Thank you for the pointers and the update!

I have fixed the issues you pointed to, I hope they are satisfactory.

@Ravenbot Ravenbot merged commit 86a528d into Ravenbrook:master Aug 8, 2021
@gareth-rees
Copy link
Member

Pull request merged — thank you for the contribution.

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.

Saving errno and GetLastError in ProtSEHFilter on Windows
4 participants