I can confirm that this issue still exists in the 295.53 drivers.
I strongly suspect that the issue is as others have surmised:
- The NVidia GL driver uses pthread_atfork() call to register a fork callback in the child process
- This fork callback in the child process attempts to lock a pthread_mutex
- That pthread_mutex was already locked by some other thread in the parent at the time that the fork() call was made, and thus has a locked state in the child process. Thus the attempt to lock the mutex in the child process hangs.
There is a workaround for this. You must compile a shared library that overrides pthread_atfork() with a no-op function, and use LD_PRELOAD to force this version of pthread_atfork() to be used. This will prevent the NVidia GL library from registering its atfork() callback and as far as I can tell has no bad side effects.
To create such a shared library, create a file fix_nvidia.c with these contents:
int __register_atfork(void (*prepare) (void), void (*parent) (void),
void (*child) (void), void *dso_handle)
fprintf(stderr, "__register_atfork ignored\n");
Then compile this into a shared library with:
gcc -fPIC -c fix_nvidia.c
gcc -shared -o fix_nvidia.so fix_nvidia.o
Now you can use LD_PRELOAD to force this function to be used:
LD_PRELOAD=/path/to/fix_nvidia.so your_program your_commandline_args
If it is working as expected, you will see a few such lines when your program starts up:
(I traced the above calls in my program and they were both from the NVidia GL library)
You can remove those fprintf calls and recompile if you don't want to see those messages; I included them just so that you can verify that you have done everything correctly.
It is likely that if your forked program is making any OpenGL calls, forcing the atfork() callback to be ignored will result in problems. I am immediately doing an exec() after my fork() (as I suspect most people are) and don't make any OpenGL calls, so whatever NVidia's child atfork() callback is doing is pointless in my program anyway.
I should add that if some other library or application code in your program legitimately calls pthread_atfork(), using this workaround will likely break your program. However, I expect that pthread_atfork() is very rarely used and for the vast majority of programs, the workaround will not cause any problems.