-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[Windows] Avoid GetModuleHandle(NULL) #2301
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned, this works when using a Microsoft linker.
What about MSYS2/Mingw and assimilated environments ?
Will they provide a Microsoft compatible linker ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put together a little executable that tests this:
running it on MSYS2 gives me the following output:
Sadly my knowledge about windows linkers isn't deep enough, but my gut feeling is that everyone who went through building a windows linker directly or indirectly implements this "feature".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good then. I was mostly concerned about MSSY2/Mingw...
Maybe we could fallback to the old behavior when required (should there be a way to detect that).
Not simple since we don't even know if such environments exist at all...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and tested a rust equivalent of your test (rustc does not use gcc but llvm/clang afaik).
Works on MINGW64 and on CLANG64 (not shown):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly I believe implementing a fallback would be quite difficult. There are two cases in which this wouldn't work:
__ImageBase
is not defined:I have never seen this in practice, might be worth to get in touch with some people who know a bit more about linkers on Windows but I've never seen it fail anywhere. As far as I know, there is no way to detect whether FFI externs are defined at compile-time. The good thing is though, should this trick fail clients will be notified by compile-time errors so it would be quickly noticed and fixed.
__ImageBase
address is wrong:This can only happen if someone redefined the variable. This is disallowed by the standard anyway (as variable names prefixed with two underscores are reserved for the compiler/implementation). I suppose in debug mode one could print a warning if
__ImageBase
diverges fromGetModuleHandle(NULL)
, although in some cases that is to be expected (e.g. when running inside a DLL).I have a high degree of confidence that this will be functional and an improvement over the current approach, however I am not an expert on Windows linkers so that's why I put it up as a draft for now. Might be worth looking into what other major libraries use this library to increase confidence in using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be another technique described in that stackoverflow link that doesn't depend on the linker. Has there been any experimentation with this? (I have not tried it myself)
https://stackoverflow.com/a/56804892
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__ImageBase
has been around for a long time (check out this blog post by Raymond Chen from 2004). I'd be surprised if we encountered any issues with it.EDIT: I didn't read the contents of the PR all that closely, so I didn't see the blog post being already linked, lol.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
GetModuleHandleEx
approach is clever and would probably work but there is another advantage of the__ImageBase
: It does not require a syscall, it has the overhead of a global variable access which makes it the most efficient and fastest option.Should there be a concern about it not working (even though we have yet to find a platform on where this doesn't work on - compatibility layers around windows have existed for decades and as maroider stated it's probably 2 decades old at this point so it's probably stable), we could lock it behind a feature gate. I'd still be in favour of making
__ImageBase
the default, as it is the more cost efficient option. Should it not be working, theGetModuleHandleEx
approach could be used.One of the big advantages is that this approach cannot silently fail. If
__ImageBase
is missing there'll be a compiler error, if its address is wrong, window creation will fail due to an invalidHINSTANCE
. I believe it would be worth it to test this feature and should there be any issues this commit can be instantly reverted and we can get back to the drawing board and figure out a hybrid approach.