gamemode: gamemodeauto: dlopen failed

Describe the bug

I am using gamemoderun %command% to initiate gamemode when launching a steam game. However according to Proton Log, gamemode isn’t functioning properly. The log has several lines of gamemodeauto: dlopen failed - libgamemode.so: cannot open shared object file: No such file or directory

To Reproduce

Launch a game on steam using startup command gamemoderun %command%

Expected behavior

Log should tell that gamemode was initiated successfully.

System Info

  • OS and version: Arch
  • GameMode Version: 1.6.1-1

Additional context

I have tried building gamemode myself from source as well as using pamac with both resulting in the same outcome.

gamemoded -s suggests that gamemode is active when the game is running. gamemoded -t gets stuck on “Supervisor tests” and spams ...Waiting for child to quit...

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 1
  • Comments: 19 (1 by maintainers)

Most upvoted comments

sigh

TL;DR: this isn’t an issue. You have nothing to worry about, gamemode functions as you expect it to, despite these errors. You don’t need the LD_PRELOAD trick either, unless gamemode doesn’t work. Check with gamemoded -s while the game is running, it should say “gamemode is active”


we are looking into why gamemoded is not running

It is running:

https://user-images.githubusercontent.com/6643565/147821858-4097857a-c6db-48b9-80bd-ef4c56b25ea4.mp4

[why gamemoded] is missing the libgamemode.so lib

From the dlopen manpage:

void *dlopen(const char *filename, int flags); … The function dlopen() loads the dynamic shared object (shared library) file named by the null-terminated string filename and returns an opaque “handle” for the loaded object. … If filename is NULL, then the returned handle is for the main program. If filename contains a slash (“/”), then it is interpreted as a (relative or absolute) pathname. Otherwise, the dynamic linker searches for the object as follows (see ld.so(8) for further details):

  • (ELF only) If the calling object (i.e., the shared library or executable from which dlopen() is called) contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the directories listed in the DT_RPATH tag are searched.
  • If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of directories, then these are searched. (As a security measure, this variable is ignored for set-user-ID and set-group-ID programs.)
  • (ELF only) If the calling object contains a DT_RUNPATH tag, then the directories listed in that tag are searched.
  • The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is checked to see whether it contains an entry for filename.
  • The directories /lib and /usr/lib are searched (in that order).

There are two calls to dlopen in the source code:

libgamemode = dlopen("libgamemode.so.0", RTLD_NOW);

and

libgamemode = dlopen("libgamemode.so", RTLD_NOW);

Neither pass NULL or a filename with a slash, therefore the dynamic linker has to search for the object. Going through these locations one by one:

  • libgamemodeauto doesn’t have a DT_RPATH. You can verify with objdump -x /usr/lib64/libgamemodeauto.so.0.0.0|grep RPATH
  • /usr/lib64/ (the location where libgamemode is) is not in LD_LIBRARY_PATH.
  • libgamemodeauto doesn’t have a DT_RUNPATH. You can verify with objdump -x /usr/lib64/libgamemodeauto.so.0.0.0|grep RUNPATH
  • Ignoring for now.
  • Neither /lib nor /usr/lib have a libgamemode in them.

So, there is only one way for the dynamic linker to find libgamemode, and that is by using /etc/ld.so.cache:

lahvuun@lahvuun ~ 0 % strings /etc/ld.so.cache|grep libgamemode
/usr/lib64/libgamemodeauto.so
/usr/lib64/libgamemode.so
/usr/lib64/libgamemodeauto.so.0
/usr/lib64/libgamemode.so.0

For whatever reason Valve, in their infinite wisdom, made it so Proton startup process ignores /etc/ld.so.cache. I don’t know how or why they did, but that’s how things are. If you’re interested, you can ping one of the Valve employees handling the GitHub issues, I bet they’d love that 😃


And now about the so-called “fix” of LD_PRELOAD="$LD_PRELOAD:/usr/\$LIB/libgamemode.so.0"!

It doesn’t accomplish much.

All that does is make gamemode active for every process that Steam starts when you click “PLAY”, which is not something you necessarily want, because not every process that Steam runs is a game. Some things are better off with a priority that is lower than the game’s, such as, oddly enough, the wineserver.

In this particular case the only difference are a few short-lived processes that during Proton’s startup. They are the source of the errors. By using LD_PRELOAD you make sure these have gamemode applied to them, which doesn’t cause any issues right now, but may (though it’s extremely unlikely) in the future.

Anyway, if you were to check which processes gamemode affects with and without that “fix”, you’d see the exact same list of:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
17655 lahvuun   18 -10   29.4m   6.4m   6.0m S   0.0   0.0   0:00.02 reaper
17662 lahvuun   11 -10    4.6m   0.9m   0.8m S   0.0   0.0   0:00.43 pv-bwrap
17765 lahvuun   10 -10   26.5m   4.2m   3.8m S   0.0   0.0   0:00.01 pressure-vessel
17789 lahvuun   21 -10   47.4m  20.2m  13.1m S   0.0   0.1   0:00.11 python3
17793 lahvuun   10 -10 1917.2m  36.4m  25.9m S   0.0   0.1   0:00.10 steam
17799 lahvuun   10 -10 2453.6m  42.7m  30.9m S   0.0   0.1   0:00.04 services.exe
17802 lahvuun   10 -10 1943.3m  35.4m  30.4m S   0.0   0.1   0:00.03 winedevice.exe
17810 lahvuun   10 -10 2082.6m  47.3m  38.8m S   0.0   0.1   0:00.05 plugplay.exe
17816 lahvuun   10 -10 2755.3m  66.4m  41.3m S   0.3   0.2   0:00.17 winedevice.exe
17851 lahvuun   10 -10 1877.0m  34.1m  30.2m S   0.0   0.1   0:00.01 svchost.exe
17856 lahvuun   10 -10 1914.2m  52.0m  43.3m S   0.0   0.2   0:00.07 tabtip.exe
17858 lahvuun   10 -10 1890.3m  28.9m  21.4m S   0.0   0.1   0:00.09 explorer.exe
17863 lahvuun   10 -10 2132.9m  37.0m  30.0m S   0.0   0.1   0:00.01 rpcss.exe

plus the game process.

The LD_PRELOAD error is not logged by Gamemode or even Steam , it is Linux’s dynamic linker logging the error. It’s simply a quirk of Steam’s usage of LD_PRELOAD that it puts both 32 and 64 bit libraries in there, meaning that regardless of the executable there will always be at least one harmless error log, for every single game launch on steam.

The amount of headspace taken up by the confusion is immeasurable though, I’ve probably had to explain this more than a few hundred times.

Could the error be somehow like hidden? It has been confused with gamemode “not working” on some thread on reddit and Lutris forums? Like at least add an FAQ or something about when troubleshooting saying “this is not an issue” and link to this issue??