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

Latest sync (0.651) causes segfault specifically on ubuntu-20.04 #1515

Closed
JohnnyMorganz opened this issue Nov 9, 2024 · 4 comments · Fixed by #1523
Closed

Latest sync (0.651) causes segfault specifically on ubuntu-20.04 #1515

JohnnyMorganz opened this issue Nov 9, 2024 · 4 comments · Fixed by #1523
Assignees
Labels
bug Something isn't working

Comments

@JohnnyMorganz
Copy link
Contributor

Attempting to sync to Luau 0.651 for luau-lsp causes a crash on ubuntu-20.04 when executing the binary: JohnnyMorganz/luau-lsp#813

Running in gdb gives:

Program received signal SIGSEGV, Segmentation fault.
0x00005555555df637 in std::_Optional_payload<Luau::FragmentParseResumeSettings, false, false, false>::_Optional_payload_base(bool, std::_Optional_payload_base<Luau::FragmentParseResumeSettings> const&) ()
(gdb) bt
#0  0x00005555555df637 in std::_Optional_payload<Luau::FragmentParseResumeSettings, false, false, false>::_Optional_payload_base(bool, std::_Optional_payload_base<Luau::FragmentParseResumeSettings> const&) ()
#1  0x00005555555df671 in std::_Optional_base<Luau::FragmentParseResumeSettings, false, false>::_Optional_base(std::_Optional_base<Luau::FragmentParseResumeSettings, false, false> const&) ()
#2  0x00005555555da9c7 in std::optional<Luau::FragmentParseResumeSettings>::optional(std::optional<Luau::FragmentParseResumeSettings> const&) ()
#3  0x00005555555daa15 in Luau::ParseOptions::ParseOptions(Luau::ParseOptions const&) ()
#4  0x0000555555d5beac in Luau::Config::Config(Luau::Config const&) ()
#5  0x0000555555d5f508 in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#6  0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#7  0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#8  0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#9  0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#10 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#11 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#12 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#13 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#14 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#15 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#16 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#17 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#18 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#19 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#20 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#21 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#22 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#23 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#24 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#25 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#26 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#27 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#28 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#29 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Confi
...
#27546 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#27547 0x0000555555d5f52c in std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<Luau::Config> >, std::is_move_constructible<Luau::Config>, std::is_move_assignable<Luau::Config> >::value, void>::type std::swap<Luau::Config>(Luau::Config&, Luau::Config&) ()
#27548 0x0000555555d5c28a in Luau::Config::operator=(Luau::Config const&) ()
#27549 0x0000555555c6443e in WorkspaceFileResolver::readConfigRec(std::filesystem::__cxx11::path const&) const ()
#27550 0x0000555555c63d05 in WorkspaceFileResolver::getConfig(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const ()
#27551 0x00005555557f2a41 in Luau::Frontend::getSourceNode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#27552 0x00005555557ed837 in Luau::Frontend::parseGraph(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, std::function<bool (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>) ()
#27553 0x00005555557eb96d in Luau::Frontend::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::optional<Luau::FrontendOptions>) ()
#27554 0x0000555555c6b4cb in WorkspaceFolder::checkStrict(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) ()
#27555 0x0000555555cf5910 in WorkspaceFolder::completion(lsp::CompletionParams const&) ()
#27556 0x00005555555fe414 in (anonymous namespace)::DOCTEST_ANON_CLASS_6::f() ()
#27557 0x00005555555fe210 in (anonymous namespace)::DOCTEST_ANON_FUNC_7() ()
#27558 0x00005555555bac3d in doctest::Context::run() ()
#27559 0x00005555555bb662 in main ()

which repeats for several stackframes (snipped), indicating a problem in the implementation for Luau::Config::operator=(Luau::Config const&) ()

https://github.com/luau-lang/luau/blob/e6bf71871a6b9f601545dba8a42ce89c6069675c/Config/src/Config.cpp#L43C1-L51C2

@JohnnyMorganz JohnnyMorganz added the bug Something isn't working label Nov 9, 2024
@JohnnyMorganz
Copy link
Contributor Author

JohnnyMorganz commented Nov 9, 2024

Can also reproduce this with luau-analyze on ubuntu-20.04, with a similar backtrace in gdb:

$ mkdir build && cd build
$ cmake ..
$ cmake --build . --target Luau.Analyze.CLI
$ touch test.lua
$ ./luau-analyze test.lua
Segmentation fault

@aatxe aatxe added the new solver This issue is specific to the new solver. label Nov 10, 2024
@aatxe aatxe removed the new solver This issue is specific to the new solver. label Nov 12, 2024
@aatxe aatxe assigned vrn-sn and aatxe and unassigned Vighnesh-V, vrn-sn and aatxe Nov 12, 2024
@vrn-sn
Copy link
Contributor

vrn-sn commented Nov 12, 2024

@JohnnyMorganz this is a sneaky bug — I believe I have a fix on my end, but I want to make sure there isn't something else going on.

Config's move constructor and assignment are both marked noexcept, but DenseHashMap's move constructor and assignment aren't. On your platform, I believe this is causing the std::swap to perform copy assignment instead of move assignment, which creates an infinite loop (Config's copy assignment calls std::swap, which calls Config's copy assignment, which calls std::swap, etc.)

Editing the previous solution I had posted before (not sure it was safe). Try going to Config.h and removing the noexcepts here:

Config(const Config& other) noexcept;
Config& operator=(const Config& other) noexcept;
Config(Config&& other) noexcept = default;
Config& operator=(Config&& other) noexcept = default;

Also, remove the noexcepts in Config.cpp for the explicitly defined copy constructor and assignment operator.

Config::Config(const Config& other) noexcept

Config& Config::operator=(const Config& other) noexcept

If that works for you, I'll put in a PR (let me know).

@JohnnyMorganz
Copy link
Contributor Author

Thanks @vrn-sn, I've tested with removing the noexcept in Config on ubuntu-20.04 via WSL and it seems to be working for me!

diff --git a/Config/include/Luau/Config.h b/Config/include/Luau/Config.h
index d6016229..64b76f07 100644
--- a/Config/include/Luau/Config.h
+++ b/Config/include/Luau/Config.h
@@ -21,10 +21,10 @@ constexpr const char* kConfigName = ".luaurc";
 struct Config
 {
     Config();
-    Config(const Config& other) noexcept;
-    Config& operator=(const Config& other) noexcept;
-    Config(Config&& other) noexcept = default;
-    Config& operator=(Config&& other) noexcept = default;
+    Config(const Config& other);
+    Config& operator=(const Config& other);
+    Config(Config&& other) = default;
+    Config& operator=(Config&& other) = default;

     Mode mode = Mode::Nonstrict;

diff --git a/Config/src/Config.cpp b/Config/src/Config.cpp
index 3760fd9e..345e039c 100644
--- a/Config/src/Config.cpp
+++ b/Config/src/Config.cpp
@@ -17,7 +17,7 @@ Config::Config()
     enabledLint.setDefaults();
 }

-Config::Config(const Config& other) noexcept
+Config::Config(const Config& other)
     : mode(other.mode)
     , parseOptions(other.parseOptions)
     , enabledLint(other.enabledLint)
@@ -40,7 +40,7 @@ Config::Config(const Config& other) noexcept
     }
 }

-Config& Config::operator=(const Config& other) noexcept
+Config& Config::operator=(const Config& other)
 {
     if (this != &other)
     {

@vrn-sn
Copy link
Contributor

vrn-sn commented Nov 12, 2024

Fix is merged. Let me know if you have any other issues!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

Successfully merging a pull request may close this issue.

4 participants