Posted on Mon 11 June 2018

Read Time: 7 minutes

Linux Game Troubleshooting: Unable to find a supported OpenGL core profile.

Continued adventures in application troubleshooting aka using strace in the most brute force sort of way.

Have you ever had one of those problems where you know the payoff isn’t worth the work, but you can’t step away because you have to solve it? That is where I am at right now. If you read my earlier post on troubleshooting, you know that I am working on getting a itch.io game to work in Linux. In that post, I fixed a few missing libraries, but then I hit a dead end. Something in my setup still wasn’t quite right.

As I also noted in that post, this is not the only way to approach solving this issue. It may not even be the best, but it is a way. My real goal here is to convince you that you shouldn’t fear the potential complexity of these tools or even your own lack of knowledge. Get in there and play around. It is the best way to learn.

So, to start, let’s set the system context. I am running run Fedora 28 on an AMD Ryzen 1700X with an Nvidia GTX 10801.

The logs reported thus:

Unable to find a supported OpenGL core profile
Failed to create valid graphics context: please ensure you meet the minimum requirements
E.g. OpenGL core profile 3.2 or later for OpenGL Core renderer
Vulkan detection: 0
No supported renderers found, exiting

Now, this is a bit surprising as I thought I had installed all the OpenGL libraries I needed. Indeed, I double checked that mesa-libGL and its corollaries were installed in both 32bit and 64bit versions. They indeed were.

I then ran ldconfig -p | grep GL to confirm that the OpenGL libraries were there.

$ ldconfig -p | grep GL
    libQt5OpenGL.so.5 (libc6,x86-64) => /lib64/libQt5OpenGL.so.5
    libQtOpenGL.so.4 (libc6,x86-64) => /lib64/libQtOpenGL.so.4
    libOpenGL.so.0 (libc6,x86-64) => /lib64/libOpenGL.so.0
    libGLdispatch.so.0 (libc6,x86-64) => /lib64/libGLdispatch.so.0
    libGLdispatch.so.0 (libc6) => /lib/libGLdispatch.so.0
    libGLX_nvidia.so.0 (libc6,x86-64) => /lib64/libGLX_nvidia.so.0
    libGLX_mesa.so.0 (libc6,x86-64) => /lib64/libGLX_mesa.so.0
    libGLX_mesa.so.0 (libc6) => /lib/libGLX_mesa.so.0
    libGLX.so.0 (libc6,x86-64) => /lib64/libGLX.so.0
    libGLX.so.0 (libc6) => /lib/libGLX.so.0
    libGLU.so.1 (libc6,x86-64) => /lib64/libGLU.so.1
    libGLU.so.1 (libc6) => /lib/libGLU.so.1
    libGLEW.so.2.0 (libc6,x86-64) => /lib64/libGLEW.so.2.0
    libGLESv2_nvidia.so.2 (libc6,x86-64) => /lib64/libGLESv2_nvidia.so.2
    libGLESv2.so.2 (libc6,x86-64) => /lib64/libGLESv2.so.2
    libGLESv1_CM_nvidia.so.1 (libc6,x86-64) => /lib64/libGLESv1_CM_nvidia.so.1
    libGLESv1_CM.so.1 (libc6,x86-64) => /lib64/libGLESv1_CM.so.1
    libGL.so.1 (libc6,x86-64) => /lib64/libGL.so.1
    libGL.so.1 (libc6) => /lib/libGL.so.1
    libEGL_nvidia.so.0 (libc6,x86-64) => /lib64/libEGL_nvidia.so.0
    libEGL_mesa.so.0 (libc6,x86-64) => /lib64/libEGL_mesa.so.0
    libEGL.so.1 (libc6,x86-64) => /lib64/libEGL.so.1

I know, now, that there is a problem in this list 2. At the time, though, it looked good.

So, this is where I found myself. No error message save a brief log file comment on OpenGL and nothing else.

Do I give up? Nope.

Is this a good way to spend my (valuable?) time? Probably not.

Am I going to dig deeper into this problem, anyway? You got it.

It’s time for strace. Now, this is not an strace tutorial 3. I am not going to show you all the cool things it can do. I am going to show how I used it in a very brute force sort of way to find out what was going wrong.

The strace tool allows us to see what an application is doing as it runs. We can see how it interacts with the system (what system calls it makes) and where it may run into to problems. This makes it a handy little tool, but it also means that it dumps a lot of information at you. In this case, I just want to know what happens with the OpenGL libraries. As you can see from the ldconfig output, not all OpenGL libraries have OpenGL in their name, but they do (usually) have GL somewhere in their name. So let’s focus our attention on lines with GL in them. Will I still get some extraneous line? Probably, but I can sort through that.

strace ./"I woke up.x86" 2>&1 | grep GL

This command launches and traces the I Woke Up game as it runs and inevitably crashes. By searching only for those transactions with a GL, I can better track the problem I am looking.


A momentary aside

Now, you might be asking what does 2>&1 mean? Good question. In your terminal, output can be sent via two different file handles: stdout aka 1 and stderr aka 2. Think of these like channels. Your terminal is tuned in to both channels, so you see both stdout and stderr in your terminal. Terminal applications, however, are often tuned to stdout and ignore stderr. This is usually a good thing except when you are troubleshooting. The strace application sends its output to stderr which means you can see it in the terminal but grep won’t. The 2>&1 tells the program to redirect all of the channel 2 output (stderr) to channel 1 (stdout). This will allow grep to find only those lines you care about.


Here is my output. Notice anything interesting (HINT: see all the -1 ENOENT (No such file or directory) lines? Those might be a problem.)

$ strace ./"I woke up.x86" 2>&1 | grep GL
openat(AT_FDCWD, "/lib/libGL.so.1", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/lib/libGLX.so.0", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/lib/libGLdispatch.so.0", O_RDONLY|O_CLOEXEC) = 4
writev(3, [{iov_base="b0\3\0\3\0\1\0", iov_len=8}, {iov_base="GLX", iov_len=3}, {iov_base="\0", iov_len=1}], 3) = 12
writev(3, [{iov_base="b0\3\0\3\0\1\0", iov_len=8}, {iov_base="GLX", iov_len=3}, {iov_base="\0", iov_len=1}], 3) = 12
openat(AT_FDCWD, "/lib/tls/i686/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/i686/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/i686/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/i686/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/i686/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/i686/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/i686/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/i686/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/sse2/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/libGLX_nvidia.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/sse2/libGLX_indirect.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/libGLX_indirect.so.0", O_RDONLY|O_CLOEXEC) = 4
writev(3, [{iov_base="b\23\3\0\3\0\0\0", iov_len=8}, {iov_base="GLX", iov_len=3}, {iov_base="\0", iov_len=1}], 3) = 12
writev(3, [{iov_base="b\0\3\0\3\0\0\0GLX\0", iov_len=12}], 1) = 12
write(2, "libGL error: ", 13libGL error: )           = 13
write(2, "libGL error: ", 13libGL error: )           = 13
read(5, "              /usr/lib/libGLX_me"..., 1024) = 1024
writev(3, [{iov_base="b\25\3\0\3\0\0\0", iov_len=8}, {iov_base="GLX", iov_len=3}, {iov_base="\0", iov_len=1}], 3) = 12

Apparently, I am missing the 32bit libraries for the Nvidia driver. Now, Fedora doesn’t include the Nvidia driver because the Nvidia driver remains closed-source. This means you will need to load your libraries from whatever repository you installed them from. You can find what repo and package that is by typing sudo dnf whatprovides libGLX_nvidia.so.0. Make sure you have installed both the 64bit and 32bit libraries. I use Negativo17’s Nvidia Repo and needed to install nvidia-driver-libs.i686.

Once you have installed, you can confirm that the libraries are in place by running lddconfig.

$ dconfig -p | grep GL
    libQt5OpenGL.so.5 (libc6,x86-64) => /lib64/libQt5OpenGL.so.5
    libQtOpenGL.so.4 (libc6,x86-64) => /lib64/libQtOpenGL.so.4
    libOpenGL.so.0 (libc6,x86-64) => /lib64/libOpenGL.so.0
    libOpenGL.so.0 (libc6) => /lib/libOpenGL.so.0
    libGLdispatch.so.0 (libc6,x86-64) => /lib64/libGLdispatch.so.0
    libGLdispatch.so.0 (libc6) => /lib/libGLdispatch.so.0
    libGLX_nvidia.so.0 (libc6,x86-64) => /lib64/libGLX_nvidia.so.0
    libGLX_nvidia.so.0 (libc6) => /lib/libGLX_nvidia.so.0
    libGLX_mesa.so.0 (libc6,x86-64) => /lib64/libGLX_mesa.so.0
    libGLX_mesa.so.0 (libc6) => /lib/libGLX_mesa.so.0
    libGLX.so.0 (libc6,x86-64) => /lib64/libGLX.so.0
    libGLX.so.0 (libc6) => /lib/libGLX.so.0
    libGLU.so.1 (libc6,x86-64) => /lib64/libGLU.so.1
    libGLU.so.1 (libc6) => /lib/libGLU.so.1
    libGLEW.so.2.0 (libc6,x86-64) => /lib64/libGLEW.so.2.0
    libGLESv2_nvidia.so.2 (libc6,x86-64) => /lib64/libGLESv2_nvidia.so.2
    libGLESv2_nvidia.so.2 (libc6) => /lib/libGLESv2_nvidia.so.2
    libGLESv2.so.2 (libc6,x86-64) => /lib64/libGLESv2.so.2
    libGLESv2.so.2 (libc6) => /lib/libGLESv2.so.2
    libGLESv1_CM_nvidia.so.1 (libc6,x86-64) => /lib64/libGLESv1_CM_nvidia.so.1
    libGLESv1_CM_nvidia.so.1 (libc6) => /lib/libGLESv1_CM_nvidia.so.1
    libGLESv1_CM.so.1 (libc6,x86-64) => /lib64/libGLESv1_CM.so.1
    libGLESv1_CM.so.1 (libc6) => /lib/libGLESv1_CM.so.1
    libGL.so.1 (libc6,x86-64) => /lib64/libGL.so.1
    libGL.so.1 (libc6) => /lib/libGL.so.1
    libEGL_nvidia.so.0 (libc6,x86-64) => /lib64/libEGL_nvidia.so.0
    libEGL_nvidia.so.0 (libc6) => /lib/libEGL_nvidia.so.0
    libEGL_mesa.so.0 (libc6,x86-64) => /lib64/libEGL_mesa.so.0
    libEGL_mesa.so.0 (libc6) => /lib/libEGL_mesa.so.0
    libEGL.so.1 (libc6,x86-64) => /lib64/libEGL.so.1
    libEGL.so.1 (libc6) => /lib/libEGL.so.1
Notice how the nvidia libraries now have (libc,x86-64) and (libc6) entries? Things are looking a lot better now.

The real proof is in the running, though. Sure enough, the game launches and runs without error. Result!!


Was this a lot of effort for a game? Yes, it was. At a certain point, though, the game wasn’t the point. We should understand the tools we have and the systems we use everyday. Black boxes are inevitable. We cannot live in a non-black-boxed world. We’d get nothing done. If we accept that everything is a black box, however, we cede control. When this comes to computers, this means we cede control over the very tools we use for communication and expression. This isn’t a call to code. Nothing I did here involved you writing in a programming language. Rather, this is an invitation to take back that really cool hunk of plastic and metal that sits on you desk or in your lap. Computers can be awesome. More importantly, their users are awesome. Learning to take control of that machine just gives you more ways of proving your excellence.


  1. Yes, I know that is asking for trouble, but I was able to get a deal on the GTX 1080, and I rarely say no to a deal. The bitcoin market has made video card pricing insane for much of the last year, so I am running with what I can get. 

  2. See the libGLX_nvidia.so.0 (libc6,x86-64) entry? Notice that there is no 32bit version (libc6) underneath it? Most Unity games need the 32bit library as well. We’ll get there, though. 

  3. Although, after my searching on the web for a tutorial to link, I think one may be needed. One of the best brief overviews comes from a 10-year-old post by Vidar Hokstrad. That is a problem. 

Author: Geoff Gimse

Category: technology

Tags: linux, fedora, technology, how-to, games

© 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.