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

Setting LD_PRELOAD in a customvars conf file does not work as expected #1158

Closed
HanPrower opened this issue Aug 30, 2024 · 7 comments
Closed
Labels
bug Something isn't working

Comments

@HanPrower
Copy link
Contributor

System Information

  • SteamTinkerLaunch version: v14.0.20240829-2
  • Distribution: Arch Linux
  • Installation Method: Flatpak

Issue Description

With my recent forays in to messing with gamescope I have bumped in to a known issue where after ~24 minutes the game will begin to lag (gamescope seems to rapidly flip between 2D and 3D power levels) (and yes! having to wait 24 minutes each time to debug it was fun 😭).

There are 2 documented workarounds:

  1. Using -e (which only works in certain scenarios - chiefly, seemingly, when launching gamescope externally from Steam)
  2. Passing a blank LD_PRELOAD= in to gamescope (i.e. LD_PRELOAD="" gamescope -f -w 2560 -h 1440 --mangoapp -- %command%

For me only the second way works, however, not when using STL.

The assumption I have arrived at rests with how loadCfg works.

The function exports into the environment, which makes sense logically. Prepare the environment, run the things in the environment.

However, this doesn't seem to pass the environment variable correctly to whatever is being run when compared to how Steam seems to do it when you put envvars in the "Launch Options" box.

I don't think export is wrong in general. It just doesn't seem to reflect how Steam works?

I'm aware overriding LD_PRELOAD is an extreme case (because doing so breaks the Steam Overlay) and usually any other set envvars aren't going to be re-manipulated by Steam, but it's worth a discussion if STL is functioning as expected.

My initial thought is that an option is added where you can either choose to export or to prefix the variables to the launch command.

Logs

None are really relevant.

@HanPrower HanPrower added the bug Something isn't working label Aug 30, 2024
@sonic2kk
Copy link
Owner

If I understand, I think SteamTinkerLaunch is functioning correctly, but that for some specific cases where Steam will override the variables (like it does for LD_PRELOAD) doesn't work, is that right?

For example if you were to manually export the variable to enable MangoHUD, would that work? Or some other variables, like Zink or something? I can't think of any more explicit examples off the top of my head 😅

If that above understanding is wrong, then you're absolutely right and we should figure out what is going on!

I don't think export is wrong in general. It just doesn't seem to reflect how Steam works?

So export will set it in the environment, but how Steam does it is that it prepends or appends to the start command. For example SOME_VAR=1 %command% will actually put that in the launch command, Steam won't use export. Steam's launch option box basically lets you manipulate the start command. I am not sure exactly how this interacts with Proton and the containers that Steam can use, but I think %command% encompasses the entire Proton start command including containers (which is why with games that accept flags you can use %command% -myopt).

So in this sense I would agree, but would also say that custom environment variables should cover most cases and are a separate use-case, they don't necessarily exist to replace the Steam launch option equivalent.


This raises a good discussion point though. In addition to your thoughts on the above, if my understanding here is all correct, perhaps we should have a way to pass options before the start command, equivalent to MYVAR=1 %command%. I think we have this for arguments following the start command but I'm not sure about before it.

But alternatively, or in addition to the above, I'm not against your idea of having an option to use prefix the start command wirh the options in the environment variables file. I think a checkbox would be good for this, grouped with those options for the commandline arguments at the top of the Game Menu. For the global environment variables file this could be useful too, but having an option for both would be tricky to avoid duplicates (maybe if both were ticked, Per-Game should take precedence).

I might be getting ahead of myself and getting the wrong end of the stick. Let me know if any of that makes sense for your use case 😅


Essentially if my understanding is correct, the problem is that exporting options in the environment variables files doesn't take priority over the ones that Steam sets (like LD_PRELOAD). But the environment variables file should work in general outside of those cases.

The solution to this would be to have some way to prepend environment variables to the Steam launch command. One way of doing this would be to have an option to prepend the environment variable file contents to the Steam start command. Another that could complement this would be an option to enter launch arguments to prepend to the Steam start command, like the one we have to append arguments to the command.

If that is all correct, this sounds reasonable to me!

@HanPrower
Copy link
Contributor Author

Your understanding of the situation I'm describing is correct :)

exporting let's Steam append what it wants back to envvars. Whereas passing variables directly doesn't let Steam do so i.e. LD_PRELOAD="" %command%

Just to confirm that the envvar files are working properly.
If I disable MangoHUD in STL, but put MANGOHUD=1 in the global-custom-vars.conf MangoHUD will appear in-game as expected.

@sonic2kk
Copy link
Owner

Okay, this is good then.


I think both approaches could be implemented together, an option to append environment variables as part of the Steam launch command would be pretty cool for this scenario and I'm sure other specific scenarios where people want to test "extremes". It would also be a bit handier than having to type out a bunch of options, it's nicer to do this from an editor. Plus it's easier to copy an environment variable file for each game you want to test, or keep a global template that you can copy and paste.

I think the approach to take here would be to have an option to enable using the Per-Game and Global custom variable files as variables to the launch command, with a note in the tooltip as you described, saying that this will prevent Steam from modifying these. Having thought more about it, to allow for a little bit of "cascading" I guess it could be called, we should be able to enable both of these options, but the per-game config file should take priority. But we can't really remove duplicates in the way I initially envisioned, in case some of the variables depend on each other (like X="10" Y="My favourite number is ${X}"). It would make the launch command a bit messy, but I think to preserve functionality as much as possible and to also allow for these cases, we can just add the Global and Per-Game if both options are enabled. Launch commands are never pretty anyway, and if we want clarity, we can log the expected output.


In terms of adding these, I wanted to see where Steam puts them, but it seems they don't get passed in the launch command. SteamTinkerLaunch will log out the "incoming start command" which is exactly what it gets from Steam, unfiltered, and this doesn't contain anything before %command%. Even running Steam from the commandline didn't display anything related to these, and a PROTON_LOG also did not. So I am not sure where we would want to set these in the launch command. Especially when it comes to things like GameScope, we would need to be mindful of where we set variables.

I think to answer this we would want to look and see what the code does right now for the variables we add to the launch command. I think we do this for some OBS flag, and I remember this was a bit tricky when it was added a couple years ago to get it to play nicely with the GameScope launch command. So this functionality is doable, we just need to make sure we export it in the right place.

I think these options can go after any that SteamTinkerLaunch adds, so they are the "last" thing added before the game start command itself.

In addition, we should update the environment variables wiki page (it needs a bit of a facelift anyway).


At some point we should also implement a way to do this with a textbox like we have for launch arguments, but we can do that separately.

I don't have much time to look at implementing this right now, if you want to you are certainly welcome to look at this, but there are no worries if not, I can take a look once I have a free moment :-)

@HanPrower
Copy link
Contributor Author

I'm just going to put some findings here for now. I may attempt a PR based on this...

If you want to see the full launch command Steam uses you can run Steam with -debug_steamapi (https://developer.valvesoftware.com/wiki/Command_line_options#Steam) if you want it in a terminal or look in ~/.steam/steam/logs/console_log.txt.

You'll then see similar to this:
[2024-09-01 11:33:40] /bin/sh\0-c\0LD_PRELOAD="" /home/hanfox/.var/app/com.valvesoftware.Steam/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=249050 -- /home/hanfox/.var/app/com.valvesoftware.Steam/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/app/utils/steamtinkerlaunch'/bin/steamtinkerlaunch waitforexitandrun '/home/hanfox/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/Dungeon of the Endless/DungeonoftheEndless.exe' -single-instance\0/Dungeon of the Endless/DungeonoftheEndless.exe' -single-instance", ProcID 8692, IP 0.0.0.0:0

You can see that the process is launched with whatever is in the "Launch Options" (on this occasion LD_PRELOAD="" %command%).

They don't appear to get parsed, they're just injected in to the command line and this is why STL doesn't see them... STL only parses $@ which is just:
waitforexitandrun '/home/hanfox/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/Dungeon of the Endless/DungeonoftheEndless.exe' -single-instance

So I would conclude they just need prefixing to any launch command STL runs 🎉


As a curiosity whilst trying to figure out the envvars I did discover an interesting tidbit, that you may know about already.

Proton has the ability to read a file called user_settings.py placed inside a compatibility tool's folder.

Placing "LD_PRELOAD": "", also works in there normally, but curiously, when STL launches the Proton tool this file isn't pulled in to the environment properly. Possibly because STL may have already set some of the variables one way or the other and the Proton tool then ignores them if set.

Not sure, just thought it was interesting 🤷‍♂️

@HanPrower
Copy link
Contributor Author

So, after trying to shove in a way to do this, I've noticed something:

As part of STL starting (main) there's are 2 functions: saveOrgVars and then emptyVars
They save a handful of currently set envvars and then blank them out.

We then wander off to prepareLaunch where loadCustomVars is, which loads the "custom-vars" files.

Next is launchSteamGame which basically sets up some bits and pieces of commands and off we shoot to startGame.

In there there's some set up for more bits and bobs... and also, just before game launch restoreOrgVars... oh. Just before game launch we reset the following to their original setting:

	LD_PRELOAD="$ORG_LD_PRELOAD"
	LD_LIBRARY_PATH="$ORG_LD_LIBRARY_PATH"
	LC_ALL="$ORG_LC_ALL"
	PATH="$ORG_PATH"

🤦

If STL doesn't restore then LD_PRELOAD="" works from the custom-vars file.

What's funny is that after the game closes STL just clears out the vars again:
emptyVars "O" "X" # clear original variables again (mostly for a continuous log (date))
and then never seems to try and restore them again.

So, instead of trying to prepend things to the launch command, I think it might be better to just not reset certain envvars if they appear in custom-vars files.

I'm just not sure the best way to check for that.

@sonic2kk
Copy link
Owner

sonic2kk commented Sep 3, 2024

Forgot to update here, but just for continuity, I agree that prepending is unnecessary for this case. In future we might have a case where we want to allow prepending arguments but it would not be necessary to use the custom environment variables file, it would be a separate use-case.

I will open an issue later today for the feature of being able to add commands before the start command, to emulate what Steam can do.

@sonic2kk
Copy link
Owner

sonic2kk commented Sep 4, 2024

I think this is fixed following #1161, thanks again!

@sonic2kk sonic2kk closed this as completed Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants