Posted on Fri 08 June 2018

Read Time: 6 minutes

Why Won’t it Start? Troubleshooting Missing Shared Libraries in Linux

I like the puzzles posed by troubleshooting. Whenever we troubleshoot something, whether an application, a classroom exercise or assignment, a research project, or something more mundane, there are always clues as to why something didn’t go quite right. If we can uncover those clues, we have a chance to make things work better the next time we attempt the task.

What follows is an example of troubleshooting in Linux. It is not the only way, it may not even be the best way, but it is one way. Note, too, that the solution is less important than the procedure. You may have a different issue, but this process can help you discover the clues to a workable solution. One of the great strengths of Linux is the power it gives it users, but that power requires a willingness to dive in and explore. While not always easy, I have found those explorations have given me a far greater appreciation for the power and potential of the modern PC.

The Problem Game

I’ve been shopping around on different gaming platforms. I’ve always liked itch.io. Their approach to indie gaming and to the broader open source community is one that I respect and value. So, I grabbed a free game from the site as a test.

I use Fedora as my everyday OS which means I try to game, as much as possible, in Linux. The game I picked up was i woke up next to you again. I picked it up in the spirit of trying new things. I haven’t played a visual novel game like this before, and I was curious.

But, there was a problem: the game wouldn’t start. Instead, I received the following error:

Not to be discouraged, I decided to figure out what the problem was.

The Log File

Don’t fear the log file. Yes, there is a lot of gobbledygook. No, I don’t know what every little thing in the file means. I know how to find out what things mean, though. That is the important part. We have manuals for a reason. So I clicked on the “Examine cause of failure” and in the log file the first error I saw was (HINT: The first major error is usually a good place to start looking.):

    Unable to preload the following plugins:
        ScreenSelector.so
After that, there was a missing data archive error (not surprising as I didn’t have any saved data) and a stack trace for the application.

At the end of the stack trace was:

    =================================================================
    Got a SIGABRT while executing native code. This usually indicates
    a fatal error in the mono runtime or one of the native libraries 
    used by your application.
    =================================================================
Linux applications often require a collection of shared libraries in order to run successfully. In this case, as the log file suggested, I was pretty sure I was missing a library or two. The question is: which ones?

Using ldd to Find Missing Libraries

When it comes to Linux applications, ldd is one of the tools we can use to discover those clues. In this case, the missing libraries. The ldd [ ldd(1) ] command lists the shared libraries that a program or shared object needs.

I wanted to start by running ldd against the main application. I suspected this wasn’t the problem, but better safe than sorry. So I opened the itch.io app and in the lower right hand corner, there is an entry that says “Show local files.”

Clicking on this in Gnome 3 (which is the default Desktop for Fedora) will open the file manager (aka Nautilus) to the directory with the game files. In the top bar you can see the path to those files. If you right-click in the file manager you will see an option to open a terminal in that folder. Otherwise, get the path (which should probably be something like /home/[your username]/.config/itch/apps/I woke up next to you again, open a terminal, and cd to the path (remember that the ~ is a shortcut to your home directory).

$ cd ~/.config/itch/apps/I woke up next to you again

In this directory there are two directories. We want the Linux folder.

    $ ls
    'I woke up_Linux'   __MACOSX
    $ cd "I woke up_Linux"/
    $ ls
    'I woke up_Data'  'I woke up.x86'

The 'I woke up.x86' file is our primary application executable. Let’s check to see if any of the shared libraries are missing.

    $ ldd "I woke up.x86" 
        linux-gate.so.1 (0xf7fc1000)
        libdl.so.2 => /lib/libdl.so.2 (0xf7f8b000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xf7f6c000)
        librt.so.1 => /lib/librt.so.1 (0xf7f62000)
        libstdc++.so.6 => /lib/libstdc++.so.6 (0xf7dd2000)
        libm.so.6 => /lib/libm.so.6 (0xf7cd0000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xf7cb2000)
        libc.so.6 => /lib/libc.so.6 (0xf7b0f000)
        /lib/ld-linux.so.2 (0xf7fc3000)

What we can see here is the list of shared libraries that the application needs and and their locations. Note that none are missing. This is a good thing, but it also doesn’t help us fix the problem. Don’t forget, though, the log file was pointing us to a game plugin called ScreenSelector.so. Notice the .so at the end of that file. That means it is a shared object that also relies on shared libraries. So, we need to find where ScreenSelector.so is hiding in our directory. Now, we could go searching through the folders by hand, but it is a lot easier just to find the file.

    $ find . -name ScreenSelector.so
    ./I woke up_Data/Plugins/x86/ScreenSelector.so
Now that we have the file location we can run ldd against it.

    $ ldd "./I woke up_Data/Plugins/x86/ScreenSelector.so"
        linux-gate.so.1 (0xf7ef5000)
        libgtk-x11-2.0.so.0 => not found
        libgdk_pixbuf-2.0.so.0 => not found
        libgobject-2.0.so.0 => not found
        libglib-2.0.so.0 => not found
        libdl.so.2 => /lib/libdl.so.2 (0xf7eb4000)
        libstdc++.so.6 => /lib/libstdc++.so.6 (0xf7d24000)
        libc.so.6 => /lib/libc.so.6 (0xf7b81000)
        /lib/ld-linux.so.2 (0xf7ef7000)
        libm.so.6 => /lib/libm.so.6 (0xf7a7f000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xf7a61000)

Note: If you are lazy, like me, you could find and run ldd all in one line.

    $ find . -name ScreenSelector.so -exec ldd {} \;
        linux-gate.so.1 (0xf7f1b000)
        libgtk-x11-2.0.so.0 => not found
        libgdk_pixbuf-2.0.so.0 => not found
        libgobject-2.0.so.0 => not found
        libglib-2.0.so.0 => not found
        libdl.so.2 => /lib/libdl.so.2 (0xf7eda000)
        libstdc++.so.6 => /lib/libstdc++.so.6 (0xf7d4a000)
        libc.so.6 => /lib/libc.so.6 (0xf7ba7000)
        /lib/ld-linux.so.2 (0xf7f1d000)
        libm.so.6 => /lib/libm.so.6 (0xf7aa5000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xf7a87000)
When you add the -exec switch to the find command you can run a command against all the files it finds. The {} expands to become the full file and path for every entry found. Make sure to close the command with \;, though.

Hey look, there are missing files there. That might be why the file isn’t loading. Great! Now we have something to fix. So, how do we find out how which packages we need?

In Fedora, you can use dnf whatprovides to find what packages have the missing libraries.

    $ dnf whatprovides libgtk-x11-2.0.so.0 libgdk_pixbuf-2.0.so.0 libgobject-2.0.so.0 libglib-2.0.so.0
    Last metadata expiration check: 11 days, 7:02:21 ago on Sun 27 May 2018 04:27:54 PM CDT.
    gtk2-2.24.32-2.fc28.i686 : GTK+ graphical user interface library
    Repo        : fedora
    Matched from:
    Provide    : libgtk-x11-2.0.so.0

    gdk-pixbuf2-2.36.12-1.fc28.i686 : An image loading library
    Repo        : fedora
    Matched from:
    Provide    : libgdk_pixbuf-2.0.so.0

    glib2-2.56.1-2.fc28.i686 : A library of handy utility functions
    Repo        : updates
    Matched from:
    Provide    : libgobject-2.0.so.0
    Provide    : libglib-2.0.so.0

    glib2-2.56.1-1.fc28.i686 : A library of handy utility functions
    Repo        : fedora
    Matched from:
    Provide    : libgobject-2.0.so.0
    Provide    : libglib-2.0.so.0

    glib2-2.56.1-2.fc28.i686 : A library of handy utility functions
    Repo        : updates
    Matched from:
    Provide    : libgobject-2.0.so.0
    Provide    : libglib-2.0.so.0

    glib2-2.56.1-1.fc28.i686 : A library of handy utility functions
    Repo        : fedora
    Matched from:
    Provide    : libgobject-2.0.so.0
    Provide    : libglib-2.0.so.0

In Debian-based systems (including Ubuntu), the apt-file command can do something very similar. See apt-file (Debian Wiki) for more information on how to use it.

What I can see from the output above is that I need to install three packages: gtk2-2.24.32-2.fc28.i686, gdk-pixbuf2-2.36.12-1.fc28.i686, and glib2-2.56.1-1.fc28.i686 in order to add all the necessary shared libraries

Fedora Note: If you look carefully at the output above, you will see both glib2-2.56.1-1.fc28.i686 and glib2-2.56.1-2.fc28.i686 are listed. Install packages from the fedora repo before the updates. In my case, the files listed in the updates repo were not even listed as found.

$ sudo dnf install gdk-pixbuf2-2.36.12-1.fc28.i686 gtk2-2.24.32-2.fc28.i686 glib2-2.56.1-1.fc28.i686

After the install process completes. Rerun your ldd command against ScreenSelector.so to confirm that all is well. If all libraries are found, you should be able to launch the program.

One Problem Solved. n Problem(s) to Go

One of the more challenging parts of the troubleshooting process is that it rarely ends easily. Quite often, you resolve one problem only to find that another one has popped up. That is what happened here. Once I installed the shared libraries, I found myself dealing with new problems. Those issues, however, can be addressed in later posts.

Author: Geoff Gimse

Category: technology

Tags: linux, fedora, technology, how-to

© Geoffrey Gimse. Built using Pelican. All photos are my own. Other images used on this site are in the Public Domain and available from Openclipart, or have been purchased for use via The Noun Project.