Skip to content

Skip empty Java paths in POLYMC_JAVA_PATHS #1696

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

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

byte-chan
Copy link

If POLYMC_JAVA_PATHS is empty or unset, the Java checker tries to check an empty path for a valid Java binary. This has the undesirable effect of potentially attempting to kill a process with PID -1, or every process for which the launcher has permission to send signals.

@LennyMcLennington
Copy link
Member

LennyMcLennington commented Mar 22, 2025

This has the undesirable effect of potentially attempting to kill a process with PID -1

Do you know what causes that? Because surely if the path is empty from some other mistake that still shouldn't happen. Feels like this fix is targeting the wrong part of the code, or at least the underlying problem should also be fixed in addition to this.

@byte-chan
Copy link
Author

Seems to be something else, actually. On my machine, the launcher tries to spawn 1490 Java checkers, and a timeout happened with a non-empty path. It's possible that the launcher is just spawning too many processes and hitting some limit.
I also tried checking whether a candidate exists and is executable with FS::ResolveExecutable, which cut the number of checkers down to just 9, and also dramatically sped up the auto-detection. Assuming it will work as intended on Windows, skipping non-executable paths could resolve this issue for the vast majority of users.
Would you like me to add that check to this PR, or would you prefer a separate PR?

@LennyMcLennington
Copy link
Member

Would you like me to add that check to this PR, or would you prefer a separate PR?

Would prefer as another commit to this PR.

@byte-chan
Copy link
Author

On second thought, this issue only really affects the Linux Java detection code, which blindly considers an excessive number of locations instead of checking a more limited set like on Windows and macOS.
Skipping non-executable paths in JavaListLoadTask::executeTask after JavaUtils::FindJavaPaths seems like a simpler solution, at the cost of (temporarily) allocating a QList<QString> with thousands of elements. Alternatively, the Linux code could filter out non-executable paths before adding them to the list.
What do you think?

@byte-chan
Copy link
Author

Looking at strace output, I could observe a failed clone(flags=CLONE_PIDFD|SIGCHLD, ...) followed by thousands of failed pipe2() syscalls, all failing with EMFILE (Too many open files), which sounds like it's trying (and failing) to keep track of thousands of processes.
Whenever the auto-detection hangs (and eventually hits the timeout), I could also see that "Java checker has failed to start." is only logged 1480 times instead of the expected 1481, which suggests that the launcher tries to spawn so many processes that even Qt (5) struggles to keep track of failure.

@LennyMcLennington
Copy link
Member

@byte-chan Why is it expected to fail 1481 times? Also should I merge the PR now? Idk whether your look into the issue with strace made you think of changing anything with it.

@byte-chan
Copy link
Author

Current develop scans several directories on Linux and blindly assumes there might be a Java executable, which adds up to 1490 candidates on my machine, 1481 of which don't even exist. The second commit cuts that down to just 9 by checking whether those candidates are actually executable instead of spawning a process to find out. In the end, the issue was the launcher spawning so many processes at once that Qt fell over, so not doing that would help.

Yes, the PR should be good to merge now.

byte-chan added 2 commits May 13, 2025 18:19
If POLYMC_JAVA_PATHS is empty or unset, the Java checker tries to check
an empty path for a valid Java binary. This has the undesirable effect
of potentially attempting to kill a process with PID -1, or every
process for which the launcher has permission to send signals.

Signed-off-by: byte-chan™ <baumi@bytesoft.dev>
Instead of blindly spawning a potentially excessive number of processes,
nonexistent or non-executable paths could be skipped by checking the
path returned by FS::ResolveExecutable. If it returns an empty string,
the path does not resolve to an executable file and can be skipped.

On Linux, this change dramatically speeds up the Java auto-detection.

Signed-off-by: byte-chan™ <baumi@bytesoft.dev>
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

Successfully merging this pull request may close these issues.

2 participants