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

tiny_tds.so not a valid win32 application #290

Closed
skiprhudy opened this issue Jul 12, 2016 · 17 comments
Closed

tiny_tds.so not a valid win32 application #290

skiprhudy opened this issue Jul 12, 2016 · 17 comments
Labels

Comments

@skiprhudy
Copy link

On Windows 10 I've got a small Rails 5 app and after discovering tiny_tds / sqlserver adapter don't support Rails v5 yet I created a quick version 4.2.6 Rails app to test connectivity to SQLEXPRESS. At first things seemed to work as after installing tiny_tds / sqlserver adapter, as I was able to successfully update a SQLEXPRESS DB using rake db:schema:load in the Rails root dir. However when I actually run the rails app itself, the app fails to load.

tiny_tds.rb is unable to require "tiny_tds/#{ver}/tiny_tds"

The LoadError is this message:

193: %1 is not a valid Win32 application. - C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/tiny_tds-1.0.4-x64-mingw32/lib/tiny_tds/2.2/tiny_tds.so

And after trying to rescue with require "tiny_tds/tiny_tds" I see:
Uncaught exception: cannot load such file -- tiny_tds/tiny_tds

Which is correct because tiny_tds is at the first location attempted but Windows says it's a bad file type.

Here is the actual path to the tiny_tds.so:
C:\Ruby22-x64\lib\ruby\gems\2.2.0\gems\tiny_tds-1.0.4-x64-mingw32\lib\tiny_tds\2.2

Here was the install:

C:\Code\PET\Spikes\ReportAppV4>gem install tiny_tds --platform=x64-mingw32
Successfully installed tiny_tds-1.0.4-x64-mingw32
Parsing documentation for tiny_tds-1.0.4-x64-mingw32
Installing ri documentation for tiny_tds-1.0.4-x64-mingw32
Done installing documentation for tiny_tds after 1 seconds
1 gem installed

gem list

tiny_tds (1.0.4 x64-mingw32)

And RubyGems Env:
RubyGems Environment:

  • RUBYGEMS VERSION: 2.4.5.1
  • RUBY VERSION: 2.2.4 (2015-12-16 patchlevel 230) [x64-mingw32]
  • INSTALLATION DIRECTORY: C:/Ruby22-x64/lib/ruby/gems/2.2.0
  • RUBY EXECUTABLE: C:/Ruby22-x64/bin/ruby.exe
  • EXECUTABLE DIRECTORY: C:/Ruby22-x64/bin

This looks to me like the .so being pre-built is not being recognized by Windows 10 as a dll type file, indicating maybe Windows 10 isn't supported yet -- couldn't find in the TinyTDS

Also here is the path before tiny_tds.rb saves it and just before requiring:

old path =
C:/Ruby22-x64/lib/ruby/gems/2.2.0/bin;C:\Ruby22-x64\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files\1E\NomadBranch;C:\Code\Tools\DevKit\bin;C:\Code\Tools\DevKit\mingw;C:\Code\Tools\DevKit\mingw\bin;C:\Program Files\Git\cmd;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn;C:\Program Files\Microsoft SQL Server\120\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn;C:\Program Files\Microsoft SQL Server\120\DTS\Binn;C:\Code\Tools\WebDrivers;C:\Program Files\nodejs\

altered path:
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/tiny_tds-1.0.4-x64-mingw32/ports/x86_64-w64-mingw32/bin;C:/Ruby22-x64/lib/ruby/gems/2.2.0/bin;C:\Ruby22-x64\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files\1E\NomadBranch;C:\Code\Tools\DevKit\bin;C:\Code\Tools\DevKit\mingw;C:\Code\Tools\DevKit\mingw\bin;C:\Program Files\Git\cmd;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn;C:\Program Files\Microsoft SQL Server\120\Tools\Binn;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn;C:\Program Files\Microsoft SQL Server\120\DTS\Binn;C:\Code\Tools\WebDrivers;C:\Program Files\nodejs\

I've tried to compile this on my (rather standard) Windows 10 but will have to work harder on that since the compile blew up (maybe I need FreeTDS from somewhere first).

Anyway I thought that it's incorrect for Windows 10 to cough on the pre-compiled gem and say it's not a valid file type, worth maybe letting y'all know. I'm happy to debug further if it will help.

@skiprhudy
Copy link
Author

skiprhudy commented Jul 12, 2016

But here's something very strange: if I put a breakpoint on line about require "tiny_tds/#{ver}/tiny_tds" it sometimes loads the file. But only if I wait for 2 or 3 minutes before continuing. And once loaded it seems to interact with DB normally.

This doesn't make any sense to me yet.

@metaskills
Copy link
Member

Thanks for stopping by and reporting the issue.

sqlserver adapter don't support Rails v5

Correct, see here for updates: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter#rails-v5-coming

But here's something very strange: if I put a breakpoint on line about require "tiny_tds/#{ver}/tiny_tds" it sometimes loads the file.

UGH! I have no idea why this might be happening.

@skiprhudy
Copy link
Author

Thanks for fast response. I'm going to investigate whether corporate encryption policy might be playing a role. The .so file is marked as encrypted -- and if decryption isn't happening correctly on access maybe that is the problem, because that would screw up windows' check on validity. It's a long shot, but I've seen this kind of thing before with binaries. I'll update as I figure out more.

@skiprhudy
Copy link
Author

Okay it's not encryption. I get similar behavior on a server 2012 machine that has no encryption of the file system. The load failure doesn't happen as often -- but it does happen. That leaves me looking at the path update statement immediately before. If I wait long enough after that PATH update but before require the tiny_tds does seem to always load. But I'm talking minutes, not seconds on windows 10. I wonder if the underlying system path update code is propagating the change immediately or not, even though it reports the added path.

This path gets added:
C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/tiny_tds-1.0.4-x64-mingw32/ports/x86_64-w64-mingw32/bin

@billkoch
Copy link

I hit this issue as well and, after some digging, I believe this is related to #287

@skiprhudy in an irb session, can you try:

require 'tiny_tds'
require 'yaml'

Assuming that works for you (it does for me), in a new irb session try:

require 'yaml'
require 'tiny_tds'

Requiring yaml before tiny_tds fails with the LoadError you describe above most times for me (it will occasionally work). Digging a bit further, yaml.rb under the covers contains require 'psych', which in turn contains require 'psych.so'

So the real culprit seems to be requiring psych.so before tiny_tds:

require 'psych.so'
require 'tiny_tds'

I still have no idea why the require 'psych.so' is messing things up, but hopefully this will help push things forward.

@stibra
Copy link

stibra commented Jul 26, 2016

Hi,

I have same problem with Ruby 2.3.1 and tiny_tds.
Everything works fine on Ruby 2.2.4.

any idea?

thanks

@diegoslice
Copy link

diegoslice commented Jul 27, 2016

Hi,

Same issue with tiny_tds.so but with an interesting twist. When I run "rails s -p 3000 -e development" using the local Thin web server, the app starts up just fine, tiny_tds loads perfectly, and I can access SQL Server as expected.

The twist is when I launch the exact same site under IIS / Helicon Zoo. Every time the site fails on the require tiny_tds.so with the following stack trace from the Helicon Zoo error page:

[tid-7169900] 193: %1 is not a valid Win32 application. - 
C:/sites/myapp/GEM_HOME/gems/tiny_tds-1.0.4-x64-mingw32/lib/tiny_tds/2.2/tiny_tds.so (LoadError) 
C:/sites/myapp/GEM_HOME/gems/tiny_tds-1.0.4-x64-mingw32/lib/tiny_tds.rb:21:in `require' 
C:/sites/myapp/GEM_HOME/gems/tiny_tds-1.0.4-x64-mingw32/lib/tiny_tds.rb:21:in `<top (required)>'
...

To figure out what the difference was in tiny_tds.rb, I modified the tiny_tds.rb file to log the FILE and ENV['PATH'] when the code is executed and commented out the begin/rescue/end block to prevent the rescue code from occurring so that the true error is displayed.

#  begin
    # Do the same host consolidation as in extconf.rb
    ports_dir = RbConfig::CONFIG["host"].gsub('i686-pc-mingw32', 'i686-w64-mingw32')
    ENV['PATH'] = "#{File.expand_path("../../ports/#{ports_dir}/bin", __FILE__)};#{old_path}"
    File.open("c:/sites/myapp/log/tds_log.txt", 'w') { |file| file.write("Start: #{Time.now}\n#{__FILE__}\n#{ENV['PATH']}\n\n") }
    require "tiny_tds/#{ver}/tiny_tds"
#  rescue LoadError
#    require 'tiny_tds/tiny_tds'
#  ensure
    ENV['PATH'] = old_path
#  end

The only difference I see is the FILE under Thin has a lower case drive letter (c:/) while under IIS/Helicon the drive letter is upper case (C:/). If I try to manually hardcode ENV['PATH'] to be lowercase when running under IIS/Helicon Zoo using something like the following, it still fails to load though.
ENV['PATH'] = "c:/sites/myapp/GEM_HOME/gems/tiny_tds-1.0.4-x64-mingw32/ports/x86_64-w64-mingw32/bin;#{old_path}"
Looking at my 'gem env', I have updated everything I can find to be upper case drive paths but see that the GEM PATHS, INSTALLATION DIRECTORY, and EXECUTABLE DIRECTORY are still lower case.

RubyGems Environment:
  - RUBYGEMS VERSION: 2.6.6
  - RUBY VERSION: 2.2.5 (2016-04-26 patchlevel 319) [x64-mingw32]
  - INSTALLATION DIRECTORY: c:/sites/myapp/GEM_HOME
  - USER INSTALLATION DIRECTORY: C:/Users/myname/.gem/ruby/2.2.0
  - RUBY EXECUTABLE: C:/Ruby22-x64/bin/ruby.exe
  - EXECUTABLE DIRECTORY: c:/sites/myapp/GEM_HOME/bin
  - SPEC CACHE DIRECTORY: C:/Users/myname/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: C:/ProgramData
  - RUBYGEMS PLATFORMS:
    - ruby
    - x64-mingw32
  - GEM PATHS:
     - c:/sites/myapp/GEM_HOME
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - C:\sites\myapp\GEM_HOME\bin
     - C:\Ruby22-x64\bin
     - C:\Ruby22-x64\devkit\bin
     - C:\Windows\system32
     - C:\Windows
     - C:\Windows\System32\Wbem
     - C:\Windows\System32\WindowsPowerShell\v1.0\
     - C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\
     - C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\
     - C:\Program Files\Microsoft SQL Server\120\Tools\Binn\
     - C:\Program Files\Microsoft SQL Server\120\DTS\Binn\
     - C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\
     - C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\
     - C:\Program Files\Common Files\RSA Shared\Auth API
     - C:\Program Files\Microsoft\Web Platform Installer\
     - C:\Program Files\mingw-w64\x86_64-5.2.0-win32-sjlj-rt_v4-rev0\mingw64\bin
     - C:\Program Files\nodejs\
     - C:\Users\myname\AppData\Roaming\npm

I'm not sure if the drive letter capitalization is what is the root cause of this or not. Does anyone know how I can update my GEM paths and directories to be upper case? I've searched through my code and my environmental variable settings for GEM_HOME and GEM_PATH and everything is capitalized that I can find.

I figure if everything is upper case, at least it would be consistent and potentially rule out a case sensitive mismatch. I found the following link to drive letter capitalization in Ruby that showed how the drive letter in windows can be upper or lower case depending on how the application is started and how Dir.pwd and Pathname.new can result in mismatched drive letters.

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23164

Hard to believe that capitalization of the drive letter may be at fault but not sure what else it could be. Thanks for any and all help!!

@modille
Copy link

modille commented Jul 27, 2016

@diegoslice good thought, although it sounds like you ruled it out yourself, since you said

If I try to manually hardcode ENV['PATH'] to be lowercase when running under IIS/Helicon Zoo using something like the following, it still fails to load though.

Also, FWIW I thought the issue may be something similar on Windows with the file path separators being / instead of \.

For example at https://github.com/rails-sqlserver/tiny_tds/blob/master/lib/tiny_tds.rb#L19 it should use File#join:

File.join('..', '..', 'ports', ports_dir, 'bin')

instead of

"../../ports/#{ports_dir}/bin"

so that the path has the proper separators (\ in this case).

But I tested that (on Windows Server 2012R2 and ruby 2.1.8p440 (2015-12-16 revision 53160) [x64-mingw32]) and it didn't make a difference.

@diegoslice
Copy link

diegoslice commented Jul 27, 2016

An update in that I did fix my remaining environment paths to be all upper case and continue to receive the same result - works in Thin but not under Helicon/IIS. Also tested was setting GEM_HOME to use both '/' instead of '' with no difference as well.

While RTFM for Helicon Zoo, I saw that I can set the worker process to use Thin instead of the Rack setup currently configured. Even with Zoo using Thin, exact same LoadError and '%1 is not a valid Win32 application'.

I'll fire up SysInternals Process Manager again and see if I can figure out any differences between running Thin on the command line with my admin credentials versus a reduced privilege IIS user account under Zoo.

@skiprhudy
Copy link
Author

So it appears the problem goes away if I put require 'tiny_tds' before just
about anything else when Rails 4 starts up. I wound up putting it in
config/boot.rb.

...
require 'tiny_tds'
require 'bundler/setup'

Maybe there's a better file to put it in for Rails init but it seemed like
much after that and it would blow up. If I get time I might try to look at
what is happening with psych loading first but can't spend time on it
immediately.

I'm using Rails 5 for work so I'll have to wait until the sqladapter for
Rails 5 comes out. If you need help testing on Windows for that I'm willing.

Thanks for all info on this, y'all -- it was driving me nuts.

On Wed, Jul 27, 2016 at 3:37 PM, diegoslice [email protected]
wrote:

An update in that I did fix my remaining environment paths to be all upper
case and continue to receive the same result - works in Thin but not under
Helicon/IIS. Also tested was setting GEM_HOME to use both '/' instead of
'' with no difference as well.

While RTFM for Helicon Zoo, I saw that I can set the worker process to use
Thin instead of the Rack setup currently configured. Even with Zoo using
Thin, exact same LoadError and '%1 is not a valid Win32 application.

I'll fire up SysInternals Process Manager again and see if I can figure
out any differences between running Thin on the command line with my admin
credentials versus a reduced privilege IIS user account under Zoo.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#290 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGJUq5tHXm1tW7jwVN8gBBLczLMaq5iFks5qZ8GDgaJpZM4JK19y
.

@sbocinec
Copy link

sbocinec commented Aug 3, 2016

Hello,

i've experienced the same issue on the Windows Server 2012 R2 running as a Qemu/KVM virtualization guest. I found, the culprit was in the CPU the VM guest was configured with- Windows was originally reporting CPU as 'QEMU Virtual CPU'. After i changed it to match the CPU model of the host (Sandybridge), problem with the '193: %1 is not a valid Win32 application. - C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/tiny_tds-1.0.4-x64-mingw32/lib/tiny_tds/2.2/tiny_tds.so' disappeared. It looks the tiny_tds requires specific CPU flags that are not present on the emulated Qemu Virtual CPU.

Can you please post the platform info where do you experience the issues?

I also confirm, that when we put 'tiny_tds' gem before any other 'ffi'-related gem (i.e. rmagick) in the Gemfile, this also helped to workaround the issue, however, then the change of the virtual CPU does not make sense... :) weird

@skiprhudy
Copy link
Author

Windows 10 on a Precision 5150 laptop i7 CPU
Windows 2012 Server R2 Datacenter HyperV VM emulating Xeon CPU E5620 (not
sure of actual host machine)

On Wed, Aug 3, 2016 at 10:14 AM, svacko [email protected] wrote:

Hello,

i've experienced the same issue on the Windows Server 2012 R2 running as a
Qemu/KVM virtualization guest. I found, the culprit was in the CPU the VM
guest was configured with- Windows was originally reporting CPU as 'QEMU
Virtual CPU'. After i changed it to match the CPU model of the host

(Sandybridge), problem with the '193: %1 is not a valid Win32 application.

C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/tiny_tds-1.0.4-x64-mingw32/lib/tiny_tds/2.2/tiny_tds.so'
disappeared. It looks the tiny_tds requires specific CPU flags that are not
present on the emulated Qemu Virtual CPU.

Can you please post the platform info where do you experience the issues?

I also confirm, that when we put 'tiny_tds' gem before any other
'ffi'-related gem (i.e. rmagick) in the Gemfile, this also helped to
workaround the issue, however, then the change of the virtual CPU does not
make sense... :) weird


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#290 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGJUq66RfxnBpXtZostMrQp_qcj2ZnrSks5qcLBygaJpZM4JK19y
.

@Annih
Copy link

Annih commented Aug 10, 2016

Hello,

I also hit this issue on ruby 2.0.0p645 on Windows Server 2012R2.
After some investigation I found that the issue is not about tiny_tds.so, but its dependencies.
Using procmon, I managed to reproduce multiples times the issue and here are my observations:

When the loading succeeds ruby did:

  1. load [GEMPATH]\tiny_tds-[GEMVERSION]\lib\tiny_tds\2.0\tiny_tds.so
  2. load [GEMPATH]\tiny_tds-[GEMVERSION]\ports\[PORTDIR]\bin\libsybdb-5.dll
  3. load [GEMPATH]\tiny_tds-[GEMVERSION]\ports\[PORTDIR]\bin\libeay32-1.0.2g-x86_64-w64-mingw32.dll
  4. load libiconv-2.dll (due to my environment it does not take the one from the port dir)
  5. load [GEMPATH]\tiny_tds-[GEMVERSION]\ports\[PORTDIR]\bin\ssleay32-1.0.2g-x86_64-w64-mingw32.dll

When the loading fail (after loading yaml for example), ruby did:

  1. load [GEMPATH]\tiny_tds-[GEMVERSION]\lib\tiny_tds\2.0\tiny_tds.so
  2. load [GEMPATH]\tiny_tds-[GEMVERSION]\ports\[PORTDIR]\bin\libsybdb-5.dll
  3. load [GEMPATH]\tiny_tds-[GEMVERSION]\ports\[PORTDIR]\bin\libeay32-1.0.2g-x86_64-w64-mingw32.dll
  4. try to load [GEMPATH]\tiny_tds-[GEMVERSION]\lib\tiny_tds\tiny_tds.so

So the issue seems to be located between the steps 3 & 4. I don't know if it's due to libeay32 or libiconv.
I think someone should try to debug the loading of these 2 dlls.

I don't have time to do it for now, I hope my observation can help.

Regards.

@dmitrynadolin
Copy link

In my case it seems that the issue was with the encoding. Setting chcp 866 helped.

@paustin01
Copy link

+1 on resolving this one

@metaskills
Copy link
Member

Going to close this issue and track it under #310 help there using OpenSSL v1.1.0 appreciated.

coderjoe added a commit that referenced this issue Dec 7, 2016
- Fix openssl being out of date. (Bumped to 1.0.2j)

- Fix freetds being out of date. (Bumped to 1.00.21)

- Fix the invalid w32 application error which occurs on x64 platforms
  occasionally due to problems with DLLs generated via dllwrap after
  being relocated.

Relates to: #290 and #310
metaskills pushed a commit that referenced this issue Mar 12, 2017
* Use OpenSSL v1.1.0e & FreeTDS v1.00.27 for Windows builds.
* Adapt dll names to 1.1.0 scheme
 - libeay -> libcrypto
 - ssleay -> libssl
* Use perl in Git installation for openssl
* OpenSSL Requires Perl >= 5.10, while the Ruby devkit uses MSYS1 with Perl 5.8.8. To overcome this, prepend Git's usr/bin to the PATH. It has MSYS2 with a recent version of perl.
* MinGW: Fix inet_pton also for 32-bit
@metaskills
Copy link
Member

Pull Request #347 pulled in OpenSSL v1.1.0 and we got new versions of TinyTDS at v1.2.0 which should solve this issue. Please reply back and let us know.

aharpervc pushed a commit to aharpervc/tiny_tds that referenced this issue Apr 9, 2020
- Fix openssl being out of date. (Bumped to 1.0.2j)

- Fix freetds being out of date. (Bumped to 1.00.21)

- Fix the invalid w32 application error which occurs on x64 platforms
  occasionally due to problems with DLLs generated via dllwrap after
  being relocated.

Relates to: rails-sqlserver#290 and rails-sqlserver#310
aharpervc pushed a commit to aharpervc/tiny_tds that referenced this issue Apr 9, 2020
…qlserver#310 rails-sqlserver#290 rails-sqlserver#349 rails-sqlserver#323 rails-sqlserver#330

* Use OpenSSL v1.1.0e & FreeTDS v1.00.27 for Windows builds.
* Adapt dll names to 1.1.0 scheme
 - libeay -> libcrypto
 - ssleay -> libssl
* Use perl in Git installation for openssl
* OpenSSL Requires Perl >= 5.10, while the Ruby devkit uses MSYS1 with Perl 5.8.8. To overcome this, prepend Git's usr/bin to the PATH. It has MSYS2 with a recent version of perl.
* MinGW: Fix inet_pton also for 32-bit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants