ruby/bigdecimal

active support cannot load bigdecimal - gets an undefined symbol error

Hellfire01 opened this issue ยท 32 comments

Steps to reproduce

Installed Ruby on an archlinux / manjaro environment ( up to date ) in a virtual machine
Installed the rails gem with a gem install rails
Tried a require 'rails' in both irb and a file

Expected behavior

No issues loading the gem

Actual behavior

The gem cannot be loaded. There seems to be an issue when trying to load the bigdecimal gem.
I have no issue when trying to load the bigdecimal gem directly.
The error is the following :

irb(main):001:0> require 'rails'
Traceback (most recent call last):
       16: from /home/matthieu/.gem/ruby/2.5.0/gems/railties-5.2.2/lib/rails/configuration.rb:4:in `<top (required)>'
       15: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
       14: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
       13: from /home/matthieu/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/core_ext/object.rb:13:in `<top (required)>'
       12: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
       11: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
       10: from /home/matthieu/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/core_ext/object/json.rb:8:in `<top (required)>'
        9: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
        8: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
        7: from /home/matthieu/.gem/ruby/2.5.0/gems/activesupport-5.2.2/lib/active_support/core_ext/big_decimal/conversions.rb:4:in `<top (required)>'
        6: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
        5: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
        4: from /home/matthieu/.gem/ruby/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.rb:9:in `<top (required)>'
        3: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:39:in `require'
        2: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
        1: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:135:in `require'
LoadError (/home/matthieu/.gem/ruby/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.so: undefined symbol: rmpd_util_str_to_d - /home/matthieu/.gem/ruby/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.so)

System configuration

Rails version: rails (5.2.2)
Ruby version: Ruby 2.5.3p105

I am at a loss on what to do to solve this issue could you please help me ?

mrkn commented

I couldn't reproduce the problem you were encountered:

irb(main):001:0> RUBY_DESCRIPTION
=> "ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]"
irb(main):002:0> gem 'rails', '5.2.2'
=> true
irb(main):003:0> gem 'bigdecimal', '1.4.2'
=> true
irb(main):004:0> require 'rails'
=> true

Could you investigate the cause of the problem on your environment?
If you don't have enough time for the investigation, please use bigdecimal 1.3.5 instead of 1.4.2.

mrkn commented

Installed Ruby on an archlinux / manjaro environment ( up to date ) in a virtual machine

@Hellfire01 How can I get the same environment of this?

mrkn commented

@Hellfire01 I found that the problem also occurs on Ubuntu bionic.

The way to avoid this problem is explicitly specifying the version of bigdecimal by gem method like:

gem 'bigdecimal', '1.4.2'

The cause is require 'bigdecimal' loads bigdecimal.so of the default-gem version rather than of the gem-installed version.

I currently don't have the way to fix this correctly.

mrkn commented

@Hellfire01 I found that the cause is the behavior of require method on Ruby 2.5.3.

On Ruby 2.6 or 2.4.5, after installing bigdecimal 1.4.2, require 'bigdecimal' loads bigdecimal.so of the gem-installed version. However, in contrast, it loads bigdecimal.so of the default gem (the bundled version) on Ruby 2.5.3.

On Ruby 2.6.0:

$ docker run --rm -it rubylang/ruby:2.6.0-bionic
root@7e104185cf11:/# gem install bigdecimal
Fetching bigdecimal-1.4.2.gem
Building native extensions. This could take a while...
Successfully installed bigdecimal-1.4.2
1 gem installed
root@7e104185cf11:/# ruby -ve 'require "bigdecimal"; p $LOADED_FEATURES.grep(/bigdecimal/)'
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux]
["/usr/local/lib/ruby/gems/2.6.0/gems/bigdecimal-1.4.2/lib/bigdecimal.so", "/usr/local/lib/ruby/gems/2.6.0/gems/bigdecimal-1.4.2/lib/bigdecimal.rb"]

On Ruby 2.5.3:

$ docker run --rm -it rubylang/ruby:2.5.3-bionic
root@689ce808458a:/# gem install bigdecimal
Fetching: bigdecimal-1.4.2.gem (100%)
Building native extensions. This could take a while...
Successfully installed bigdecimal-1.4.2
1 gem installed
root@689ce808458a:/# ruby -ve 'require "bigdecimal"; p $LOADED_FEATURES.grep(/bigdecimal/)'
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
["/usr/local/lib/ruby/2.5.0/x86_64-linux/bigdecimal.so"]

On Ruby 2.4.5:

$ docker run --rm -it rubylang/ruby:2.4-bionic
root@17a964abcb3a:/# gem install bigdecimal
Fetching: bigdecimal-1.4.2.gem (100%)
Building native extensions. This could take a while...
Successfully installed bigdecimal-1.4.2
1 gem installed
root@17a964abcb3a:/# ruby -ve 'require "bigdecimal"; p $LOADED_FEATURES.grep(/bigdecimal/)'
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-linux]
["/usr/local/lib/ruby/gems/2.4.0/gems/bigdecimal-1.4.2/lib/bigdecimal.so", "/usr/local/lib/ruby/gems/2.4.0/gems/bigdecimal-1.4.2/lib/bigdecimal.rb"]

Will give you the output I have on all of the instructions you used as soon as I can have access to my computer.
To have the same environment, I could give you the virtual image of the VM I am using if you wish, you should have the same issue.
The environment is a new manjaro / archlinux one, it has nothing installed on it ( or at least, no program that would tamper with the environment that I would know about ). Installed Ruby with pacman and then installed the gem kimura - all of it's dependencies got installed automatically - and rails.
The issue occurs when one of those two gems tries to require bigdecimal. I have no issues when trying to directly load bigdecimal.

mrkn commented

@Hellfire01 Would you please examine the following step on your environment?

  1. Assume bigdecimal 1.4.2 is installed on Ruby 2.5.3 (it should already be satisfied)
  2. Execute irb
  3. Evaluate require "bigdecimal"
  4. Evaluate $LOADED_FEATURES.grep(/bigdecimal/)
  5. Report the last result here

will do

mrkn commented

I reported the problem of require method in Ruby 2.5 on CRuby's Redmine.
See https://bugs.ruby-lang.org/issues/15500

So, when I go a gem list I get bigdecimal (1.4.2, default: 1.3.4)
ruby --version outputs ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
And finaly, when I use irb and use the given instructions, I get :

irb(main):001:0> require "bigdecimal"
=> true
irb(main):002:0> $LOADED_FEATURES.grep(/bigdecimal/)
=> ["/usr/lib/ruby/2.5.0/x86_64-linux/bigdecimal.so"]

mrkn commented

@Hellfire01 Thank you for your investigation.
The result means your issue is due to the behavior of the require method in Ruby 2.5.

The easiest way to avoid this is specifying bigdecimal's version by gem method in your script or Gemfile.

thanks but I am unsure I can do that easily as the issue appears when I require rails or kimura with use the gem through active support. Not sure iff changing the gem files of the gems I use is a good idea.
Started using other gems in the mean time as I do not need them directly. If there is a big issue, I will very simply roll back on Ruby 2.4. Thank you for pointing that that version works

mrkn commented

@Hellfire01 Sorry for the inconvenience. I have no way to resolve this issue in bigdecimal.

By the way, I couldn't understand the reason why you cannot put gem "bigdecimal", "1.4.2" line in Gemfile. You don't need to modify any gem libraries. If you encountered this issue in your Rails application, you only need to modify Gemfile of your Rails application.

oh ok, thanks for the tip I will try that.
I usually only tend to do a require without a gemfile and thought that it was the gem that imposed the version of it's dependencies.

mrkn commented

@Hellfire01 I found the reason why 2.5's require is broken. This is it: https://bugs.ruby-lang.org/issues/15545

The next minor release of 2.5 may include the fix.

mrkn commented

@Hellfire01 Sorry, the previous comment is wrong. I believed that I found the cause of the bug, but I noticed that it is incorrect. The investigation is continued by the ruby core team.

thanks for the notification ^^

vihai commented

This is becoming a major issue to me because a mere "gem update" will break any system with ruby 2.5.
Isn't there a way to prevent installing bigdecimal-1.4.3 on systems with incompatible ruby?

mrkn commented

@vihai You can stick a library version by adding the following line in Gemfile of your application:

gem "bigdecimal", "1.3.5"
mrkn commented

@vihai If you don't use bundler, you can stick a library version by adding gem "bigdecimal", "1.3.5" at the top of your script files.

I'm using 2.5.5 and still having the same problem, was this already fixed?

mrkn commented

@rafaelfranca Could you tell me how to reproduce?

I confirmed that the problem has been fixed at 2.5.5:

On 2.5.5:

$ docker run --rm -it rubylang/ruby:2.5.5-bionic /bin/sh -exc 'gem install bigdecimal; ruby -v -rbigdecimal -rbigdecimal/util -ep'
+ gem install bigdecimal
Fetching bigdecimal-1.4.3.gem
Building native extensions. This could take a while...
Successfully installed bigdecimal-1.4.3
1 gem installed
+ ruby -v -rbigdecimal -rbigdecimal/util -ep
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
$

On 2.5.3:

$ docker run --rm -it rubylang/ruby:2.5.3-bionic /bin/sh -exc 'gem install bigdecimal; ruby -v -rbigdecimal -rbigdecimal/util -ep'
+ gem install bigdecimal
Fetching: bigdecimal-1.4.3.gem (100%)
Building native extensions. This could take a while...
Successfully installed bigdecimal-1.4.3
1 gem installed
+ ruby -v -rbigdecimal -rbigdecimal/util -ep
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
Traceback (most recent call last):
        5: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        4: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        3: from /usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.3/lib/bigdecimal/util.rb:9:in `<top (required)>'
        2: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:34:in `require'
        1: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:130:in `rescue in require'
/usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:130:in `require': /usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.3/lib/bigdecimal/util.so: undefined symbol: rmpd_util_str_to_d - /usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.3/lib/bigdecimal/util.so (LoadError)
$

That is a good question ๐Ÿ˜….

I'm using a ubuntu trusty image with a custom built ruby 2.5.5, totally based on the v2_5_5 tag. I'm not sure if I need to build ruby in a special way to avoid this issue or if this issue only happens because I'm using ubuntu trusty.

But by installing bigdecimal 1.4.3 and requiring bigdecimal/util on that setup I can reproduce that error.

mrkn commented

@rafaelfranca

a custom built ruby 2.5.5

Could you please tell me the arguments of configure you specified?

I'm not sure if I need to build ruby in a special way to avoid this issue

As you can see in this build script, the ruby in the docker image I used for the previous confirmation is built in normal way.

./configure --prefix="$(PREFIX)" --without-valgrind debugflags="-g3 -ggdb"` those are the arguments.

So, when I go a gem list I get bigdecimal (1.4.2, default: 1.3.4)
ruby --version outputs ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
And finaly, when I use irb and use the given instructions, I get :

irb(main):001:0> require "bigdecimal"
=> true
irb(main):002:0> $LOADED_FEATURES.grep(/bigdecimal/)
=> ["/usr/lib/ruby/2.5.0/x86_64-linux/bigdecimal.so"]

Sorry to trouble you, for the same thing I'm getting [].

@Hellfire01 Would you please examine the following step on your environment?

  1. Assume bigdecimal 1.4.2 is installed on Ruby 2.5.3 (it should already be satisfied)
  2. Execute irb
  3. Evaluate require "bigdecimal"
  4. Evaluate $LOADED_FEATURES.grep(/bigdecimal/)
  5. Report the last result here

[].

I had to update Ruby in order to avoid having the issues ( using 2.6.3 currently, it has no issues with bigdecimal or rails ) and therefor I don't have the issues or the previous environment anymore.
I don't know if I can o something to help now sorry

mrkn commented

I've released the new version 1.4.4.
Please try with this version again.

I'm now getting NoMethodError: undefined method interpret_loosely' for BigDecimal:Class`. The reasons is that maybe the C extension was cached by bundler and didn't compile again, but I'm posting here to see if anyone else got that.

In the hopes that it helps someone: After trying everything, after verifying that it was already in my gem list, I just went ahead and experimentally ran gem install bigdecimal for giggles. That solved my problem and I can brew again fine now.

Clear the gem file.lock by: removing all gems and redo bundle install solved the issue for me.

In my case ubuntu-dev-tools was not installed:
sudo apt-get install ubuntu-dev-tools