gamemode icon indicating copy to clipboard operation
gamemode copied to clipboard

gamemodeauto: dlopen failed

Open GottaSlay opened this issue 2 years ago • 19 comments

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

GottaSlay avatar Nov 11 '21 05:11 GottaSlay

I'm getting this on games launched with gamemoderun %command% as well. I only noticed it about a week ago, while troubleshooting a game. The last time I made a proton log before that was in late October, and that didn't have the dlopen failed messages.

gamemoded -s reports gamemode is active when a steam game is launched with gamemoderun. gamemoded -t passes all tests for me.

Since my version is one behind yours, and 1.6.1 is from Feburary anyway, might it be an issue with Proton or Steam?

System Info

  • OS and version: Fedora 35 KDE
  • GameMode Version: 1.6-3

DonKatsu avatar Nov 26 '21 09:11 DonKatsu

I'm getting these messages too with Proton 6.3-8. That said, gamemode works as expected. /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor has ondemand when the game is not running and performance when it is, the process also gets reniced correctly.

This seems to be a harmless message, akin to ERROR: ld.so: object '/home/lahvuun/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.

Lahvuun avatar Dec 05 '21 12:12 Lahvuun

I'm getting it in every game but when I run gamemoded -s it says it's active.

gardotd426 avatar Dec 08 '21 03:12 gardotd426

Interesting, I see that ysblokje didnt include any reference or details about requiring the libgamemode0 in the PKGBUILD. https://aur.archlinux.org/packages/gamemode-git/

I do see a seperate PKGBUILD that seems to only include the 32 bit libraries. https://aur.archlinux.org/packages/lib32-gamemode-git/

In Summary(Using opensuse as an example):

In opensuse make sure you install the libgamemode0 and libgamemodeauto0 for both 64 and 32 bit. image

Make sure the daemon is running image

Run the gamemode tests to make sure you are good image

If using gnome, I recommend you install and turn on the gamemode extension

Set your game launcher option gamemoderun %command%

Additonal lib information(information, listing, etc) from a rpm perspective of where the libs should be installed. Note that this changes depending on the architecture and distribution you are using. image

mikeyjoel avatar Dec 24 '21 18:12 mikeyjoel

The Arch repo packages definitely include libgamemodeauto.so.

> pacman -Ql gamemode      
gamemode /etc/
gamemode /etc/security/
gamemode /etc/security/limits.d/
gamemode /etc/security/limits.d/10-gamemode.conf
gamemode /usr/
gamemode /usr/bin/
gamemode /usr/bin/gamemoded
gamemode /usr/bin/gamemoderun
gamemode /usr/include/
gamemode /usr/include/gamemode_client.h
gamemode /usr/lib/
gamemode /usr/lib/gamemode/
gamemode /usr/lib/gamemode/cpugovctl
gamemode /usr/lib/gamemode/gpuclockctl
gamemode /usr/lib/libgamemode.so
gamemode /usr/lib/libgamemode.so.0
gamemode /usr/lib/libgamemode.so.0.0.0
gamemode /usr/lib/libgamemodeauto.so
gamemode /usr/lib/libgamemodeauto.so.0
gamemode /usr/lib/libgamemodeauto.so.0.0.0
gamemode /usr/lib/pkgconfig/
gamemode /usr/lib/pkgconfig/gamemode.pc
gamemode /usr/lib/pkgconfig/libgamemodeauto.pc
gamemode /usr/lib/systemd/
gamemode /usr/lib/systemd/user/
gamemode /usr/lib/systemd/user/gamemoded.service
gamemode /usr/share/
gamemode /usr/share/dbus-1/
gamemode /usr/share/dbus-1/services/
gamemode /usr/share/dbus-1/services/com.feralinteractive.GameMode.service
gamemode /usr/share/licenses/
gamemode /usr/share/licenses/gamemode/
gamemode /usr/share/licenses/gamemode/LICENSE.txt
gamemode /usr/share/man/
gamemode /usr/share/man/man1/
gamemode /usr/share/man/man1/gamemoderun.1.gz
gamemode /usr/share/man/man8/
gamemode /usr/share/man/man8/gamemoded.8.gz
gamemode /usr/share/metainfo/
gamemode /usr/share/metainfo/io.github.feralinteractive.gamemode.metainfo.xml
gamemode /usr/share/polkit-1/
gamemode /usr/share/polkit-1/actions/
gamemode /usr/share/polkit-1/actions/com.feralinteractive.GameMode.policy

Same for lib32-gamemode

> pacman -Ql lib32-gamemode
lib32-gamemode /usr/
lib32-gamemode /usr/lib32/
lib32-gamemode /usr/lib32/libgamemode.so
lib32-gamemode /usr/lib32/libgamemode.so.0
lib32-gamemode /usr/lib32/libgamemode.so.0.0.0
lib32-gamemode /usr/lib32/libgamemodeauto.so
lib32-gamemode /usr/lib32/libgamemodeauto.so.0
lib32-gamemode /usr/lib32/libgamemodeauto.so.0.0.0
lib32-gamemode /usr/lib32/pkgconfig/
lib32-gamemode /usr/lib32/pkgconfig/gamemode.pc
lib32-gamemode /usr/lib32/pkgconfig/libgamemodeauto.pc
lib32-gamemode /usr/share/
lib32-gamemode /usr/share/licenses/
lib32-gamemode /usr/share/licenses/lib32-gamemode

gardotd426 avatar Dec 25 '21 01:12 gardotd426

🤔 Interesting

Would a soft link solve the issue then? For example: ln -s /usr/lib64/libgamemode.so /usr/lib/libgamemode.so

And then the same for each lib that is missing if it works.

The rpm package has the following in opensuse:: /usr/lib/libgamemode.so.0 /usr/lib/libgamemode.so.0.0.0 /usr/lib/libgamemodeauto.so.0 /usr/lib/libgamemodeauto.so.0.0.0 /usr/lib64/libgamemode.so /usr/lib64/libgamemode.so.0 /usr/lib64/libgamemode.so.0.0.0 /usr/lib64/libgamemodeauto.so /usr/lib64/libgamemodeauto.so.0 /usr/lib64/libgamemodeauto.so.0.0.0 /usr/lib64/pkgconfig/libgamemodeauto.pc /usr/share/licenses/libgamemode-devel /usr/share/licenses/libgamemode0 /usr/share/licenses/libgamemodeauto0 /usr/share/licenses/libgamemode-devel/LICENSE.txt /usr/share/licenses/libgamemode0/LICENSE.txt /usr/share/licenses/libgamemodeauto0/LICENSE.txt

mikeyjoel avatar Dec 26 '21 06:12 mikeyjoel

I guess Fedora is different but on Linux /usr/lib64 is a symlink already to /usr/lib.So those files already exist in both places.

file /usr/lib64
/usr/lib64: symbolic link to lib

See:

>find /usr/lib64/ | grep gamemode   

/usr/lib64/libgamemodeauto.so.0
/usr/lib64/libgamemode.so.0
/usr/lib64/libgamemode.so
/usr/lib64/pkgconfig/libgamemodeauto.pc
/usr/lib64/pkgconfig/gamemode.pc
/usr/lib64/libgamemodeauto.so
/usr/lib64/systemd/user/gamemoded.service
/usr/lib64/libgamemodeauto.so.0.0.0
/usr/lib64/libgamemode.so.0.0.0
/usr/lib64/gamemode
/usr/lib64/gamemode/gpuclockctl
/usr/lib64/gamemode/cpugovctl
>find /usr/lib/ | grep gamemode  

/usr/lib/libgamemodeauto.so.0
/usr/lib/libgamemode.so.0
/usr/lib/libgamemode.so
/usr/lib/pkgconfig/libgamemodeauto.pc
/usr/lib/pkgconfig/gamemode.pc
/usr/lib/libgamemodeauto.so
/usr/lib/systemd/user/gamemoded.service
/usr/lib/libgamemodeauto.so.0.0.0
/usr/lib/libgamemode.so.0.0.0
/usr/lib/gamemode
/usr/lib/gamemode/gpuclockctl
/usr/lib/gamemode/cpugovctl
> find /usr/lib32 | grep gamemode

/usr/lib32/libgamemodeauto.so.0
/usr/lib32/libgamemode.so.0
/usr/lib32/libgamemode.so
/usr/lib32/pkgconfig/libgamemodeauto.pc
/usr/lib32/pkgconfig/gamemode.pc
/usr/lib32/libgamemodeauto.so
/usr/lib32/libgamemodeauto.so.0.0.0
/usr/lib32/libgamemode.so.0.0.0

There's no symlinking to be done.

gardotd426 avatar Dec 26 '21 07:12 gardotd426

No, every modern distribution has lib and lib64 symlinked. Old 32-bit applications will look for /lib which is the same as /lib64 for 64 applications.

Not different, it's a standard defined in the FHS.

At this point @GottaSlay already distro hopped, gave up or found the solution.

Hopefully this issue helps anyone else that runs into this.

mikeyjoel avatar Dec 27 '21 22:12 mikeyjoel

It seems to be an issue with steam because running gamemode outside it doesn't have this problem. I've managed to fix it by adding the LD_PRELOAD="$LD_PRELOAD:/usr/\$LIB/libgamemode.so.0" enviroment variable to the launch options. After that the error went away.

Giovani1906 avatar Dec 30 '21 03:12 Giovani1906

Not an issue with Steam. Valve is not responsible for configuring your environment variables.

Either you are running isolated (snap, flatpak) or your environment variable is not setup on your host.

mikeyjoel avatar Dec 30 '21 22:12 mikeyjoel

Then care to explain why it works outside Steam and not inside it? The package has been installed through Gentoo's emerge. I've used LD_DEBUG=libs and it shows searching for it at the correct location but can't find it so the conclusion, on my side, that it's a problem with Steam's runtime. I don't want to disable the Steam runtime because that would be a really bad idea.

Giovani1906 avatar Dec 30 '21 23:12 Giovani1906

@Giovani1906 are you sure gamemode doesn't work with Steam? The error message should be harmless.

See if it takes effect while your game is running, check the CPU governor and process niceness, or whichever options you have enabled.

Lahvuun avatar Dec 31 '21 00:12 Lahvuun

I would worry about error messages. Users should be listing their /lib with something like ls /lib grep libgamemode to make sure they have it available.

Once that's done, then make sure that systemd from the user scope is running gamemoded. Running systemctl --user status gamemoded.service will provide you with the status(if running, enabled, etc). User scoped units are saved at $HOME/.config/systemd/user/default.target.wants

All those are requirements to make sure that gamemoded is really running on your system. No errors should be output when running it manually or trough steam.

mikeyjoel avatar Dec 31 '21 00:12 mikeyjoel

I would worry about error messages.

That's not how it works. The example @Lahvuun gave:

This seems to be a harmless message, akin to ERROR: ld.so: object '/home/lahvuun/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.

Which is 100% confirmed by Valve themselves to be a harmless error. DXVK and vkd3d-proton (as well as wine) also give harmless/expected error messages that don't mean anything (and are actually expected/normal behavior).

You worry about error messages like these when they coincide with something not working. If gamemode is working despite those errors (which is easy to confirm), then yes, the errors are meaningless.

gardotd426 avatar Dec 31 '21 04:12 gardotd426

There is something called log levels, trace, debug, info, warning, error and fatal. If the developer considered that to be an error and is harmless than Feral/Valve/Others in this case should log this as a warning, not an ERROR.

Very basic stuff for devs when using a logging system. I would still pay attention as to why this is an error and make sure this is not affecting performance and in this case. ld.so is supposed to be substituting a library, so yes, I would 100% investigate why the ELF class is not being properly loaded in this case this is documented here.

Always, always look at errors and don't tell people to ignore them unless there is documentation on it. The error could be related to something else like in this case (going back to the main issue) dlopen failed.

mikeyjoel avatar Dec 31 '21 10:12 mikeyjoel

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.

mdiluz avatar Dec 31 '21 10:12 mdiluz

Yeah, but that was a really bad example and a very standard one. Nothing to do with the issue opened here to begin with and bad practice and/or not good from a logging standard perspective. We are looking into why gamemoded is not running and is missing the libgamemode.so lib, not why a linker is not able to open a 32/64 library which is a known error. This is why we ask for logs in the first place to analyze the entire process since gamemoded is a different process and has nothing to do with how the game launches.

mikeyjoel avatar Dec 31 '21 10:12 mikeyjoel

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.

Lahvuun avatar Dec 31 '21 13:12 Lahvuun

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??

jh-devv avatar Jan 23 '24 16:01 jh-devv