Skip to content

Honor ignore_disable_switch for inherited DOORSTOP_INITIALIZED - #109

Open
mohui666 wants to merge 1 commit into
NeighTools:masterfrom
mohui666:fix/ignore-inherited-doorstop-initialized
Open

Honor ignore_disable_switch for inherited DOORSTOP_INITIALIZED#109
mohui666 wants to merge 1 commit into
NeighTools:masterfrom
mohui666:fix/ignore-inherited-doorstop-initialized

Conversation

@mohui666

Copy link
Copy Markdown

Summary

ignore_disable_switch already exists so launchers that break environment isolation (Steam is called out in config.h) cannot kill Doorstop with DOORSTOP_DISABLE. The same launchers also leak DOORSTOP_INITIALIZED.

mono_doorstop_bootstrap treats any inherited DOORSTOP_INITIALIZED as "we already ran" and returns before loading the target assembly. Verbose log from a Steam-launched Unity Mono game (Legend of Mortal / 活侠传):

CONFIG: General.ignore_disable_switch = true
Doorstop enabled!
Installing IAT hooks
Got mono_jit_init_version at ...
Starting mono domain "Unity Root Domain"
DOORSTOP_INITIALIZED is set! Skipping!

BepInEx never reaches Doorstop.Entrypoint.Start.

This also matches #73 (game process restarts itself and inherits both variables).

Change

  • After loading config, if ignore_disable_switch is on, clear inherited DOORSTOP_INITIALIZED and DOORSTOP_DISABLE (Windows + *nix).
  • Gate in-process re-entry with a static flag instead of trusting a pre-set env var.
  • Still skip when DOORSTOP_INITIALIZED is set and the switch is off (existing behavior).

Tested

Unity 2020.3 Mono x86, Steam app 1859910, BepInEx 6 BE, ignore_disable_switch = true. After this change Doorstop logs Opening assembly and BepInEx chainloader starts without running the game elevated.

Notes

Not changing the default of ignore_disable_switch (still false). Callers that already set it for Steam should get the rest of the intended behavior.

Steam and self-restarts leak DOORSTOP_INITIALIZED into the new process.
Doorstop then skips Mono bootstrap even when ignore_disable_switch is
set, so BepInEx never reaches Doorstop.Entrypoint.Start.
Clear the inherited flags after config load, and use a process-local
flag for genuine in-process re-entry. Fixes the Steam/Windows case
seen with Unity Mono titles (e.g. Legend of Mortal) and the restart
path in NeighTools#73.

@ManlyMarcoManlyMarco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine. I'll merge after giving others a chance to review.

@arrowmaster

Copy link
Copy Markdown
Contributor

This is an interesting conundrum. The original intent of the ignore_disable_switch does appear to be broken. I didn't even realize that option existed. However I would consider usage of it after this fix to be dangerous (at least on *nix) until #88 is fixed, as usage of this setting would cause any sub processes started by Unity to also get hooked by Doorstop and have their stdout broken. This could have disastrous results with any usages of subprocesses to return data back to the Unity process through stdout, resulting in no data returned.

What situation have you found that needs this fixed? I know the common one where starting a game which requires SteamWorks without Steam running causes the game to launch Steam with arguments to launch itself again after Steam starts.

I'm not objecting to the fix (although I would prefer the LOG messages for clearing the envvars to only happen when they are actually set), but I'm questioning why this setting is needed if its been broken for so long already and we have an open bug that would be made worse if it was used. If the setting is kept then it should actually work.

@mohui666

Copy link
Copy Markdown
Author

这是一个有趣的难题。ignore_disable_switch 的原始设计意图似乎确实被破坏了。 ignore_disable_switch 之前甚至都没注意到这个选项的存在。然而,我认为在修复此问题之前(至少在 *nix 系统上),在 #88 问题解决之前使用它都是危险的,因为使用此设置会导致 Unity 启动的任何子进程也被 Doorstop 拦截,从而破坏它们的 stdout。这可能会对任何通过 stdout 将数据返回给 Unity 进程的子进程造成灾难性后果,导致无法返回任何数据。

您发现什么情况需要修复这个问题?我知道一个常见的情况是,在 Steam 未运行的情况下启动需要 SteamWorks 的游戏,会导致游戏启动 Steam 时,SteamWorks 会带有启动 Steam 的参数,从而在 Steam 启动后再次启动游戏自身。

我并不反对这个修复方案(虽然我希望只有在实际设置了环境变量时才显示清除环境变量的日志信息),但我质疑的是,既然这个设置已经失效这么久了,而且我们还有一个未解决的 bug,启用这个设置只会让问题更严重,为什么还需要保留它呢?如果保留这个设置,它应该就能正常工作了。

This issue usually occurs at random.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mohui666@arrowmaster@ManlyMarco