Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gamemodeauto: dlopen failed #345

Open
GottaSlay opened this issue Nov 11, 2021 · 19 comments
Open

gamemodeauto: dlopen failed #345

GottaSlay opened this issue Nov 11, 2021 · 19 comments

Comments

@GottaSlay
Copy link

GottaSlay commented Nov 11, 2021

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

@DonKatsu
Copy link

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

@Lahvuun
Copy link

Lahvuun commented Dec 5, 2021

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.

@gardotd426
Copy link

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

@mikeyjoel
Copy link

mikeyjoel commented Dec 24, 2021

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

@gardotd426
Copy link

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

@mikeyjoel
Copy link

mikeyjoel commented Dec 26, 2021

🤔 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

@gardotd426
Copy link

gardotd426 commented Dec 26, 2021

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.

@mikeyjoel
Copy link

mikeyjoel commented Dec 27, 2021

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.

@Giovani1906
Copy link

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.

@mikeyjoel
Copy link

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.

@Giovani1906
Copy link

Giovani1906 commented Dec 30, 2021

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.

@Lahvuun
Copy link

Lahvuun commented Dec 31, 2021

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

@mikeyjoel
Copy link

mikeyjoel commented Dec 31, 2021

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.

@gardotd426
Copy link

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.

@mikeyjoel
Copy link

mikeyjoel commented Dec 31, 2021

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.

@mdiluz
Copy link
Contributor

mdiluz commented Dec 31, 2021

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.

@mikeyjoel
Copy link

mikeyjoel commented Dec 31, 2021

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.

@Lahvuun
Copy link

Lahvuun commented Dec 31, 2021

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:

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

@sofiedotcafe
Copy link

sofiedotcafe commented Jan 23, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants