Advertisement

Occasionally I get some really weird errors when I try to install gems using gem or bundler. It took me some time to find out the reason for this. Read on if you’d like to hear the full story.

Installation of rubygem “unf_ext” failed

In most cases those errors occur after an upgrade of ruby. To give you an example, read the following error message from installing the unf_ext-gem. After reading the message the first time, my first guess was a missing library stdc++.

# Version of Rubygems
gem -v
# => 2.4.5.1

# Install the gem
gem install unf_ext -v 0.0.7.1
# => Building native extensions.  This could take a while...
# => ERROR:  Error installing unf_ext:
# =>         ERROR: Failed to build gem native extension.
# =>
# =>     /usr/bin/ruby -r ./siteconf20151030-29963-guv2om.rb extconf.rb
# => checking for main() in -lstdc++... *** extconf.rb failed ***
# => Could not create Makefile due to some reason, probably lack of necessary
# => libraries and/or headers.  Check the mkmf.log file for more details.  You may
# => need configuration options.
# =>
# => Provided configuration options:
# =>         --with-opt-dir
# =>         --without-opt-dir
# =>         --with-opt-include
# =>         --without-opt-include=${opt-dir}/include
# =>         --with-opt-lib
# =>         --without-opt-lib=${opt-dir}/lib
# =>         --with-make-prog
# =>         --without-make-prog
# =>         --srcdir=.
# =>         --curdir
# =>         --ruby=/usr/bin/$(RUBY_BASE_NAME)
# =>         --with-static-libstdc++
# =>         --without-static-libstdc++
# =>         --with-stdc++lib
# =>         --without-stdc++lib
# => /usr/lib/ruby/2.2.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
# => You have to install development tools first.
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:541:in `try_link0'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:556:in `try_link'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:735:in `try_func'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:966:in `block in have_library'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:911:in `block in checking_for'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:351:in `block (2 levels) in postpone'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:321:in `open'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:351:in `block in postpone'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:321:in `open'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:347:in `postpone'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:910:in `checking_for'
# =>         from /usr/lib/ruby/2.2.0/mkmf.rb:961:in `have_library'
# =>         from extconf.rb:6:in `<main>'
# => 
# => extconf failed, exit code 1
# => 
# => Gem files will remain installed in /home/user/.gem/ruby/2.2.3/gems/unf_ext-0.0.7.1 for inspection.
# => Results logged to /home/user/.gem/ruby/2.2.3/extensions/x86_64-linux/2.2.0/unf_ext-0.0.7.1/gem_make.out

Checking if the required library is available

At first I tried to locate the missing library – I could also have used find instead: Everything looked good, the library exists on my system. So I moved on and tried strace to see what file the compiler looks for.

# make sure the db of locate is up to date
updatedb

# locate the library
locate -b "stdc++"
# => [...]
# => /usr/lib/libstdc++.a
# => /usr/lib/libstdc++.so
# => /usr/lib/libstdc++.so.6
# => /usr/lib/libstdc++.so.6.0.20
# => [...]

Checking which files the compiler looks for

To find out which files are involved in some error, I normally use strace, especially if I get “Permissions Denied” errors for no obvious reason. I reduce the output, I chose to filter out any non-file “syscall”.

strace -e trace=file gem install unf_ext

This command outputs its findings to STDOUT by default. But it was far too much information for STDOUT, so I wanted to save them to the hard disk at /tmp/output.txt

strace -e trace=file -o /tmp/output.txt gem install unf_ext

… but when I opened the file using less, it was empty. Strange!

less /tmp/output.txt

After that I checked its size. Mmmh… 0 bytes. That’s even stranger.

ls -al /tmp/output.txt
# => -rw-r--r-- 1 user user 0 Oct 30 07:28 /tmp/output.txt

Checking available space in filesystem

Following my gut instinct, I used df to see what the usage of the file systems look like. Ok, /tmp/ has a usage of 100%. That’s definitely not good.

df -h
# => Filesystem  Size  Used Avail Use% Mounted on
# =>
# => [...]
# => tmpfs       2.0G  2.0G     0 100% /tmp
# => [...]

But why is all that space used? I had a look at /tmp/ with ls. Damn! There’s a temporary file using all space in /tmp. Looking at it’s file name it seems to be used by “Wireshark”. For all of you who don’t know “Wireshark”. It’s an open source network sniffer, the successor of “Ethereal”. I use it quite a lot to troubleshoot network issues.

ls -al /tmp/
# => [...]
# => -rw-r--r-- 1 user user 2007171072 Oct 30 07:27 /tmp/wireshark_pcapng_any_20151007191347_q6LGpN
# => [...]

The file I saw is a temporary one, used by “Wireshark” to save all captured network traffic during a live capture. Now we’ve got two options: Looking for the “Wireshark”-window and close the program or kill it.

Cleanup file system

Closing “Wireshark” via “File > Close” makes “Wireshark” deleting its temporary files automatically. If you kill it, you need to remove the file in /tmp manually. Therefor I decided to close “Wireshark” regularly. When I checked the file system usage, only 4% was used by some smaller files.

df -h
# => [...]
# => tmpfs                                     2.0G   65M  1.9G   4% /tmp
# => [...]

Installing the gem again

After /tmp/ had been cleaned up, the installation of the “unf_ext”-gem was a success.

gem install unf_ext
# => Building native extensions.  This could take a while...
# => Successfully installed unf_ext-0.0.7.1
# => 1 gem installed

Conclusion

Ok. I must be honest: In most cases I forgot that I ran wireshark in the background and it filled up my /tmp/-directory. There might be other programs as well, which fill up your /tmp-directory. A usage 100% can break “Rubygems” and other programs which use /tmp to store temporary files. Even docker uses it, to store temporary trusted-docker-files during a build-run. So be careful not fill it up to much.

Thanks for reading!

Discussion

If you found a mistake in this article or would like to contribute some content to it, please file an issue in this Git Repository

Disclaimer

The contents of this article are put together to the best of the authors' knowledge, but it cannot be guaranteed that it's always accurate in any environment. It is up to the reader to make sure that all information found in this article, does not do any damage to the reader's working environment or wherever this information is applied to. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, arising from, out of or in connection with this article. Please also note the information given on the Licences' page.