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

Build-time DLLs can be different than runtime DLL versions #60

Open
larskanis opened this issue Jul 30, 2017 · 8 comments
Open

Build-time DLLs can be different than runtime DLL versions #60

larskanis opened this issue Jul 30, 2017 · 8 comments

Comments

@larskanis
Copy link
Member

larskanis commented Jul 30, 2017

What problems are you experiencing?

As discovered in #53 , updates to DLLs, which are bundled with RI2 as builtin DLLs, are not available to the ruby process at runtime. The ruby builtin DLLs are always preferred over any other DLLs. It can therefore happen, that gems are linked against a newer version of the DLL than the one that is loaded at runtime.

Steps to reproduce

  • Install RubyInstaller-2.4.1-1-x64 (not the latest version)
  • Run ridk install 1 2 3
  • Run ridk exec pacman -S mingw-w64-x86_64-openssl
  • Run gem install openssl
  • Check runtime version: ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
    => OpenSSL 1.0.2k 26 Jan 2017
  • Check build version: ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
    => OpenSSL 1.0.2l 25 May 2017

What's the output from ridk version?

@larskanis
Copy link
Member Author

larskanis commented Jul 30, 2017

The current work-around for this kind of issues is to build and install a renewed version of RI2. This automatically ships the latest MSYS2 DLLs, so that builtin DLLs and package DLLs are the same.

A longer term solution would be to change the current side-by-side assembly mechanism, which is used by ruby.exe, in such a way, that it doesn't apply to gems installed after RI2 installation. This should be possible by injecting a RI2 specific XML manifest into all extension so files, which are shipped with the RI2 setup.

@MSP-Greg
Copy link
Contributor

First of all, do OPENSSL_LIBRARY_VERSION & OPENSSL_VERSION have their lookups flipped? 2.4.1-1-x64 was built with 1.0.2k, but after your replacement, it's running on 1.0.2l. Maybe I'm missing something...

Thanks for the responses. I've got some weekend stuff to take care, but I'd like to think about all the different issues and use cases.

This should be possible by injecting a RI2 specific XML manifest into all extension so files

Are you also referring to copying dll files from the MSYS2 folders? Given that MSYS2 only allows one version of a package...

I don't like the idea of multiple MSYS2 installations.

@MSP-Greg
Copy link
Contributor

@larskanis

Okay, now I really gotta run, but I checked some code testing I had done. If in operating_system.rb we change the following:

RubyInstaller::Runtime.add_dll_directory("#{RbConfig::CONFIG['bindir']}/ruby_builtin_dlls")

to:

RubyInstaller::Runtime.add_dll_directory("#{RbConfig::CONFIG['bindir']}/ruby_builtin_dlls")
RubyInstaller::Runtime.enable_dll_search_paths 

Are we causing any issues? It might take care of the specific issue you mentioned (package update, but no ruby changes), don't have time to swap packages, I just renamed MSYS folder...

As I mentioned, I'll collect my thoughts later...

@MSP-Greg
Copy link
Contributor

@larkanis

First of all, guess I was distracted this morning, I missed 'Run gem install openssl ' in your first message.

Anyway, I'm moving between my trunk build, 2.4.1-2, etc.

From what I can tell, the manifest only needs to contain at most one file libgmp-10.dll, which I believe is used by x64-msvcrt-ruby2*0.dll.

The ruby builtin DLLs are always preferred over any other DLLs

I'm too tired to check this further, but I was going crazy because that wasn't what I was finding. But, I think the issue was that I was renaming my MSYS folder. If it's not found, is the ruby_builtin_dlls folder not added to the 'dll path' (and, maybe, no error message)? I was testing EventMachine with OpenSSL, and installed it with 1.0.2, then I reinstalled my 1.1.0 package. Checked for EM, and it found the default OpenSSL 1.0.2 dlls in ruby_builtin_dlls, which wasn't the case with MSYS renamed... Thanks.

@mohits
Copy link
Collaborator

mohits commented Nov 27, 2022

Hi @larskanis - do you think we can close this? Or do you feel that this is still pending to resolve?

@larskanis
Copy link
Member Author

This issue is still present, but most of the time it can be fixed by updateing to the latest RubyInstaller release. I didn't find a better solution so far, but maybe in the future. So let it open!

@mohits
Copy link
Collaborator

mohits commented Nov 27, 2022

I will check again in a few months :)

@mohits
Copy link
Collaborator

mohits commented Oct 12, 2024

Hi @larskanis - in Nov 2022, I promised to check again on this issue in a few months. What do you feel now? :-)

larskanis added a commit that referenced this issue Dec 26, 2024
…on.so file

So far ruby.exe and rubyw.exe contained a process-global manifest for side-by-side loading.
This way the DLLs bundled to RubyInstaller could be moved to a dedicated directory, so that they aren't loaded accidently by other apps because they are in the PATH.

It was introduced in b2bd630
The downside of a global manifest is that the dependent DLLs are always preferred over other DLL versions with the same name.
This caused for instance openssl.gem to fail, when the libssl DLL linked at build time was newer than the libssl bundled with RubyInstaller.

This patch introduces manifests per extension.so file with dedicated private dependencies.
This way the bundled openssl.so is directly linked to it's own libssl.dll by an embedded manifest.
It's similar to static linking libssl into openssl.so, but it allows to use unchanged libssl.dll from MINGW packages.

If a new openssl.gem version is installed per "gem install openssl", it links to MSYS2/MINGW packages at build time.
Since the resulting openssl.so doesn't contain the manifest, it also links to the MINGW packages at run time.

Fixes #60
larskanis added a commit that referenced this issue Dec 26, 2024
…on.so file

So far ruby.exe and rubyw.exe contained a process-global manifest for side-by-side loading.
This way the DLLs bundled to RubyInstaller could be moved to a dedicated directory, so that they aren't loaded accidently by other apps because they are in the PATH.

It was introduced in b2bd630
The downside of a global manifest is that the dependent DLLs are always preferred over other DLL versions with the same name.
This caused for instance openssl.gem to fail, when the libssl DLL linked at build time was newer than the libssl bundled with RubyInstaller.

This patch introduces manifests per extension.so file with dedicated private dependencies.
This way the bundled openssl.so is directly linked to it's own libssl.dll by an embedded manifest.
It's similar to static linking libssl into openssl.so, but it allows to use unchanged libssl.dll from MINGW packages.

If a new openssl.gem version is installed per "gem install openssl", it links to MSYS2/MINGW packages at build time.
Since the resulting openssl.so doesn't contain the manifest, it also links to the MINGW packages at run time.

Patching extension.so files requires to add all single files recursively as file tasks.

Fixes #60
larskanis added a commit that referenced this issue Dec 26, 2024
…on.so file

So far ruby.exe and rubyw.exe contained a process-global manifest for side-by-side loading.
This way the DLLs bundled to RubyInstaller could be moved to a dedicated directory, so that they aren't loaded accidently by other apps because they are in the PATH.

It was introduced in b2bd630
The downside of a global manifest is that the dependent DLLs are always preferred over other DLL versions with the same name.
This caused for instance openssl.gem to fail, when the libssl DLL linked at build time was newer than the libssl bundled with RubyInstaller.

This patch introduces manifests per extension.so file with dedicated private dependencies.
This way the bundled openssl.so is directly linked to it's own libssl.dll by an embedded manifest.
It's similar to static linking libssl into openssl.so, but it allows to use unchanged libssl.dll from MINGW packages.

If a new openssl.gem version is installed per "gem install openssl", it links to MSYS2/MINGW packages at build time.
Since the resulting openssl.so doesn't contain the manifest, it also links to the MINGW packages at run time.

Patching extension.so files requires to add all single files recursively as file tasks.

Fixes #60
larskanis added a commit that referenced this issue Dec 27, 2024
…on.so file

So far ruby.exe and rubyw.exe contained a process-global manifest for side-by-side loading.
This way the DLLs bundled to RubyInstaller could be moved to a dedicated directory, so that they aren't loaded accidently by other apps because they are in the PATH.

It was introduced in b2bd630
The downside of a global manifest is that the dependent DLLs are always preferred over other DLL versions with the same name.
This caused for instance openssl.gem to fail, when the libssl DLL linked at build time was newer than the libssl bundled with RubyInstaller.

This patch introduces manifests per extension.so file with dedicated private dependencies.
This way the bundled openssl.so is directly linked to it's own libssl.dll by an embedded manifest.
It's similar to static linking libssl into openssl.so, but it allows to use unchanged libssl.dll from MINGW packages.

If a new openssl.gem version is installed per "gem install openssl", it links to MSYS2/MINGW packages at build time.
Since the resulting openssl.so doesn't contain the manifest, it also links to the MINGW packages at run time.

Patching extension.so files requires to add all single files recursively as file tasks.

Fixes #60
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

No branches or pull requests

3 participants