VirtualGL / virtualgl

Main VirtualGL repository
https://VirtualGL.org
Other
690 stars 104 forks source link

Steam + VGL crashes when attempting to launch a game #25

Closed dcommander closed 8 years ago

dcommander commented 8 years ago

Refer to this thread. Specifically, this has been tested under Fedora 22 with the July 8, 2016 build of Steam (installed from the Fedora DNF repository) but probably affects all Linux platforms. It has specifically been tested with Dota 2 but probably affects most or all Steam games.

I've reproduced the problem, but I'm clueless as to what's causing it. Symptomatically, what's happening is that, when the VGL faker attempts to load a symbol from libGL using dlsym(), dlsym() returns the interposed symbol from the VGL faker instead. No idea why, but it seems that Steam is somehow interfering with VGL's function dispatching mechanism. When I've seen such problems in the past with other applications, I was able to work around them by setting VGL_GLLIB=/usr/lib64/libGL.so.1 or VGL_GLLIB=/usr/lib/libGL.so.1, which forces VirtualGL to load the "real" OpenGL functions directly from the underlying OpenGL library instead of relying on the dynamic loader to pick those symbols from the next library in the search order. That doesn't work with Steam, however.

I've spent 15 hours of unpaid labor and am unfortunately no closer to solving this. I give up.

dcommander commented 8 years ago

This is definitely related to LD_PRELOAD. What seems to be happening is that Steam adds ~/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so:~/.local/share/Steam/ubuntu12_64/gameoverlayrenderer.so to the existing LD_PRELOAD variable set by vglrun, so the resulting LD_PRELOAD variable is:

libdlfaker.so:libvglfaker.so:~/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so:~/.local/share/Steam/ubuntu12_64/gameoverlayrenderer.so

Because I have no access to the gameoverlayrenderer.so source, I'm not sure exactly what that interposer is doing, but in my testing, it is clear that gameoverlayrenderer.so has to be preloaded ahead of VirtualGL for things to work properly. For instance, if I edit

~/.local/share/Steam/steamapps/common/dota 2 beta/game/dota.sh

and add

export LD_PRELOAD=~/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so:~/.local/share/Steam/ubuntu12_64/gameoverlayrenderer.so:libdlfaker.so:libvglfaker.so

to the top, I can make Dota 2 launch and play correctly. This exposes a second issue whereby the game locks up when exiting it (still investigating that.)

As far as I can tell, the LD_PRELOAD variable is modified within some non-hackable part of Steam. I think a good argument could be made that this is incorrect behavior on Steam's part. gameoverlayrenderer.so should be as close to the application in the preload order as possible, and other interposers should be placed after it.

Still investigating how I might be able to work around this within VirtualGL, but I wanted to share my findings thus far. Note that I also tried disabling the in-game overlay, in hopes that that would make Steam stop trying to preload gameoverlayrenderer.so, but no such luck. :|

dcommander commented 8 years ago

Update:

The underlying cause of these problems is that gameoverlayrenderer.so interposes dlsym(), glXGetProcAddress(), and glXGetProcAddressARB(), thus creating a situation similar to the one that used to exist when the nVidia 180.xx drivers were interposing dlsym() (refer to https://sourceforge.net/p/virtualgl/mailman/message/22260702 and https://sourceforge.net/p/virtualgl/mailman/message/21377897 for historical context.) However, in this case, setting VGL_GLLIB doesn't work around it. gameoverlayrenderer.so is closed-source, so it's difficult to ascertain exactly what's happening, but this seems to be an approximation:

Things I tried:

Workarounds:

Note that I can no longer reproduce the lock-up when exiting Dota. That may have been due to my own error.

Longer-term, my best advice would be to encourage Valve to change the order of LD_PRELOAD so that gameoverlayrenderer.so is put ahead of any other interposers, or to allow such behavior to be configured with an environment variable. It seems that we're not the only ones having problems with gameoverlayrenderer.so (https://github.com/GhostSquad57/Steam-Installer-for-Wheezy/issues/37).

dcommander commented 8 years ago

NOTE:

A better workaround is to set the launch options for each game to:

LD_PRELOAD="${LD_PRELOAD/libdlfaker.so:libvglfaker.so:/}:libdlfaker.so:libvglfaker.so" %command%

This at least allows the issue to be worked around without hacking the individual launch scripts, and it works for games without launch scripts. However, it's still not particularly user-friendly.

NOTE: unfortunately I'm now seeing the lock-up again when exiting games. :(

Sunzhou-H commented 6 years ago

Ubuntu 16.04 can't use this workaround because of bash issue. A workaround for Ubuntu 16.04 is to set the launch options to:

LD_PRELOAD="${LD_PRELOAD#libdlfaker.so:libvglfaker.so:}:libdlfaker.so:libvglfaker.so" %command%

This launch option works well for dota2.