-
Notifications
You must be signed in to change notification settings - Fork 296
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
Work around popen not being thread safe on MacOS #695
Conversation
@@ -120,7 +120,7 @@ namespace vcpkg::Commands::DependInfo | |||
std::string value = iter->second; | |||
try | |||
{ | |||
return std::stoi(value); | |||
return std::max(std::stoi(value), NO_RECURSE_LIMIT_VALUE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who says a user puts only numbers >= -1 in here?
src/vcpkg/base/system.cpp
Outdated
} | ||
catch (std::exception&) | ||
{ | ||
Checks::msg_exit_with_message(VCPKG_LINE_INFO, msgOptionMustBeInteger, msg::option = "VCPKG_MAX_CONCURRENCY"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BillyONeal Should we throw if VCPKG_MAX_CONCURRENCY
is invalid or should we simply continue with std::thread::hardware_concurrency()
@omartijn Gotcha! I created a unit test that executes the command Here are the results:
The problem is that in random positions the string returned from the child process is missing a The segfault comes into place when someone tries to read at index > 38 in this case. |
I fixed another crash, but there are multiple ones: #695 (comment) |
Never mind, the crash isn't fixed |
@autoantwort If unit tests succeed on OSX in CI and the message EDIT: Never mind, I noticed that the debug message I added wasn't printed. |
Because you have to pass |
Seems that it fails with std::async because that also calls |
@autoantwort Although it shouldn't matter but did you also try to set the buffer back to 1023 at the line you commented about #695 (comment) ? |
Finally found it. The pclose call also has to be protected by the mutex. |
All the errors I got happens before the fgets line. This has nothing to do with the buffer size. All got all errors while the buffer size was 1023. |
Apply this patch to fix the pipeline: diff --git a/src/vcpkg/base/system.process.cpp b/src/vcpkg/base/system.process.cpp
index c6eb7820..c00713c8 100644
--- a/src/vcpkg/base/system.process.cpp
+++ b/src/vcpkg/base/system.process.cpp
@@ -960,7 +960,15 @@ namespace vcpkg
return format_system_error_message("feof", errno);
}
- int ec = pclose(pipe);
+ int ec;
+ {
+#if defined(__APPLE__)
+ // `pclose` sometimes returns 127 on OSX when executed in parallel.
+ // Related: https://github.com/microsoft/vcpkg-tool/pull/695#discussion_r973364608
+ std::lock_guard guard(mtx);
+#endif
+ ec = pclose(pipe);
+ }
if (WIFEXITED(ec))
{
ec = WEXITSTATUS(ec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I approve the macOS specific changes
@autoantwort Thanks a lot for your help! |
It is even documented that our use of vcpkg-tool/src/vcpkg/base/system.process.cpp Lines 485 to 491 in c0e76df
|
I think adding more context to the quote makes more sense:
My interpretation is that this is restating how
doesn't guarantee But all of this is largely philosophical. Given the evidence in this thread, I think adding a lock around |
Does that mean you are OK with this change? Note that it is currently unable to merge because you are marked 'request changes' |
Thanks :) |
Whoop whoop. Thank you! ❤️ |
Related microsoft/vcpkg#26651
vcpkg occasionally crashed atdecompress_in_parallel
>cmd_execute_and_capture_output_parallel
because threads that are launched bycmd_execute_and_capture_output_parallel
were writing to the result vector without locking the vector.Not a problem because they access different indexes of the vector and don't cause a resize.
@omartijn Thanks for providing the debug information.
max_concurrency()
get_concurrency()
returnedint
which didn't make any sense because there can't be-1
threads.