Skip to content

Problems with GHCi and NVIDIA drivers on Ubuntu 12.04 #42

Closed
dagit opened this Issue Jul 23, 2013 · 1 comment

2 participants

@dagit
Haskell OpenGL member
dagit commented Jul 23, 2013

From HOpenGL mailing list: http://www.haskell.org/pipermail/hopengl/2013-July/001055.html

When I try to run OpenGL examples on Ubuntu 12.04 with the latest
Haskell platform (2013.2.0.0, incl. GHC 7.6.3), the following happens:

svenpanne@svenpanne:~/haskell-platform-2013.2.0.0/packages/GLUT-2.4.0.0/examples/RedBook$
runhaskell Smooth.hs
freeglut (Smooth.hs):  ERROR:  Internal error <FBConfig with necessary
capabilities not found> in function fgOpenWindow
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  4 (X_DestroyWindow)
  Resource id in failed request:  0x0
  Serial number of failed request:  37
  Current serial number in output stream:  40

I am using an x86_64 Ubuntu 12.04 distro (with some minor corporate
modifications, but they probably don't matter here) with NVIDIA
drivers. This means that the dynamic linker will load NVIDIA's
libGL.so, as can be seen e.g. here:

svenpanne@svenpanne:~$ ldd /usr/lib/x86_64-linux-gnu/libglut.so | grep libGL
libGL.so.1 => /usr/lib/nvidia-current/libGL.so.1 (0x00007f1ddc76e000)
svenpanne@svenpanne:~$ dpkg -S /usr/lib/nvidia-current/libGL.*
nvidia-current: /usr/lib/nvidia-current/libGL.so
nvidia-current: /usr/lib/nvidia-current/libGL.so.1
nvidia-current: /usr/lib/nvidia-current/libGL.so.310.51

This is OK, and this is the libGL.so which will be found by 'ld' when
one simply specifies '-lglut' for compilation via gcc. This can be
seen e.g. when tracing things during the linking stage of the "Hello,
world!" example from the Red Book:

svenpanne@svenpanne:~/redbook$ strace -f gcc hello.o -lglut 2>&1 |
grep 'libglut\|libGL' | grep -v ENOENT
[pid  7782] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
{st_mode=S_IFREG|0644, st_size=287720, ...}) = 0
[pid  7782] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
O_RDONLY) = 8
[pid  7782] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
O_RDONLY) = 13
[pid  7782] stat("/usr/lib/nvidia-current/libGL.so.1",
{st_mode=S_IFREG|0644, st_size=1099504, ...}) = 0
[pid  7782] open("/usr/lib/nvidia-current/libGL.so.1", O_RDONLY) = 14
[pid  7782] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
O_RDONLY) = 5
[pid  7782] open("/usr/lib/nvidia-current/libGL.so.1", O_RDONLY) = 12
[pid  7782] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
O_RDONLY) = 8
...

But things get weird when one explicitly specifies '-lGLU and -lGL' in
addition to '-lglut' (something GHC's package system is actually doing
behind the scenes, too):

svenpanne@svenpanne:~/redbook$ strace -f gcc hello.o -lglut -lGLU -lGL
2>&1 | grep 'libglut\|libGL' | grep -v ENOENT
[pid  7943] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
{st_mode=S_IFREG|0644, st_size=287720, ...}) = 0
[pid  7943] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
O_RDONLY) = 8
[pid  7943] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libGLU.so",
{st_mode=S_IFREG|0644, st_size=449168, ...}) = 0
[pid  7943] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libGLU.so",
O_RDONLY) = 9
[pid  7943] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libGL.so",
{st_mode=S_IFREG|0644, st_size=390352, ...}) = 0
[pid  7943] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libGL.so",
O_RDONLY) = 10
[pid  7943] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libglut.so",
O_RDONLY) = 4
[pid  7943] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libGL.so",
O_RDONLY) = 5
...

This happens because of there is a symbolic link in the standard
library search path for gcc, which is part of a Mesa package:

svenpanne@svenpanne:~$ ll /usr/lib/x86_64-linux-gnu/libGL.so
lrwxrwxrwx 1 root root 13 Jun 18 22:54
/usr/lib/x86_64-linux-gnu/libGL.so -> mesa/libGL.so
svenpanne@svenpanne:~$ dpkg -S /usr/lib/x86_64-linux-gnu/libGL.so
libgl1-mesa-dev: /usr/lib/x86_64-linux-gnu/libGL.so

Funnily enough, when you run the application later, it will use
NVIDIA's libGL.so, because the dynamic linker consults
/etc/ld.so.{cache,conf} and of course does not look into gcc's
library search path:

svenpanne@svenpanne:~/redbook$ ldd a.out | grep libGL
libGL.so.1 => /usr/lib/nvidia-current/libGL.so.1 (0x00007f7841b34000)

So in a nutshell: If you are explicit about your library dependencies,
things are inconsistent on Ubuntu. Because of this, GHCi loads Mesa's
libGL.so (found via 'gcc --print-names), which does not work with
NVIDIA drivers.

The question is: What to do about this? Adding /usr/lib/nvidia-current
to OpenGLRaw's library-dirs is wrong, because this will fail when you
e.g. temporarily switch to Mesa for OpenGL. I have the very strong
feeling that this is a Ubuntu bug: The link
'/usr/lib/x86_64-linux-gnu/libGL.so => mesa/libGL.so' is simply wrong
in the presence of NVIDIA drivers, and one should fix this by making
it point to /usr/lib/nvidia-current/libGL.so. A quick Google search
found that other people have similar problems:

https://answers.launchpad.net/ubuntu/+source/nvidia-graphics-drivers/+question/182181
http://techtidings.blogspot.de/2012/01/problem-with-libglso-on-64-bit-ubuntu.html
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=630527

@svenpanne
Haskell OpenGL member

Closing this, I don't think it is relevant anymore.

@svenpanne svenpanne closed this Mar 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.