Closed shawnanastasio closed 3 years ago
Update: My patch to use std::locale("")
as the global locale ends up breaking the game in other ways, though it does solve the crashes. It causes the following error messages to be printed:
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
8,736
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
8,736
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
8,768
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
8,800
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
8,832
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
9,440
[WARNING] /Volumes/shawnanastasio_home/opt/supertux/src/supertux/sector.cpp:664 [/Volumes/shawnanastasio_home/opt/supertux/src/util/reader_error.hpp:64] <stream>:1: expected real in expression:
9,536
Commenting out the call to std::locale::global
all together solves both the crashes and the error messages above:
--- a/src/supertux/main.cpp
+++ b/src/supertux/main.cpp
@@ -569,7 +569,7 @@ Main::run(int argc, char** argv)
// NOTE: when moving to C++ >= 17, keep the try-catch block, but use std::locale:global(std::locale(""));
try
{
- std::locale::global(boost::locale::generator().generate(""));
+ //std::locale::global(std::locale(""));
// Make boost.filesystem use it
boost::filesystem::path::imbue(std::locale());
}
This is obviously not an upstreamable change, but perhaps the call to std::locale::global can be ifdef'd out for macOS at least? The default locale on macOS should be UTF-8 compatible, so these calls shouldn't be necessary.
@Grumbel If you have time, please take a look. I'm not knowledgeable enough about this.
The expected real in expression
issue is caused by locale getting into the serialization and replacing the dot with a comma and can be fixed with this patch:
--- a/src/supertux/game_object_factory.cpp
+++ b/src/supertux/game_object_factory.cpp
@@ -284,6 +284,7 @@ std::unique_ptr<GameObject>
GameObjectFactory::create(const std::string& name, const Vector& pos, const Direction& dir, const std::string& data) const
{
std::stringstream lisptext;
+ lisptext.imbue(std::locale::classic());
lisptext << "(" << name << "\n"
<< " (x " << pos.x << ")"
<< " (y " << pos.y << ")" << data;
No idea what's going wrong with boost::locale::generator().generate("")
.
@shawnanastasio Could you please incorporate the suggested changes by grumbel and update the PR? Thanks!
@shawnanastasio Could you please incorporate the suggested changes by grumbel and update the PR? Thanks!
Do you mean I should create a PR that incorporates Grumbel's changes along with my own? (This ticket is just a bug report.) Unless I'm mistaken, @Grumbel's patch doesn't affect the crashing with boost_locale, so we still need to decide how to handle that. My current thinking is that it might be best to just conditionally guard out the std::locale::global
call on macOS, but if the project is fine with switching out the boost_locale call entirely for std::locale("")
and potentially introducing a C++17 dependency, then I can submit that as well.
Does anybody know what boost::locale::generator().generate("")
actually does? The documentation says it's setting the "system default locale", but which is that actually? It's not the same as std::locale("")
, when I test it it looks more like std::locale::classic()
, but if that's the case that whole block of code would seem unnecessary.
For reference:
std::locale::classic()
- standard C locale, defaultstd::locale()
- the globally set locale (i.e. what was set with std::locale::global(loc)
)std::locale("")
- the user preferred locale (i.e. what was set with LC_ALL
or LANG
environment variables)This all goes back to #706
Also worth mentioning that none of our serialization code currently handles locales, so my above patch isn't enough, the Writer
and maybe other stuff would need to get fixed as well, as all of them expect std::locale::classic()
.
After a bit of further digging, it seems that boost::locale::generator().generate("")
does give you something similar to std::locale("")
, but with all the numeric formatting changed stripped out. So it won't break input/output, while std::locale("")
would.
Back to the original issue, fixing the issue by just moving the #endif
a bit further down to make all the locale initialization Win32-only is certainly an option, as I don't think we are using it for anything other than boost::filesystem::path::imbue()
, which itself is only necessary for Win32 to begin with.
However I don't think the crash is a fault of the code to begin with. Seems more like some incompatible library build slipped in or something along the lines, boost::locale::generator().generate("")
shouldn't crash just by itself.
After a bit of further digging, it seems that
boost::locale::generator().generate("")
does give you something similar tostd::locale("")
, but with all the numeric formatting changed stripped out. So it won't break input/output, whilestd::locale("")
would....
However I don't think the crash is a fault of the code to begin with. Seems more like some incompatible library build slipped in or something along the lines,
boost::locale::generator().generate("")
shouldn't crash just by itself.
Interesting. It definitely sounds like some upstream incompatibility with boost-locale and macOS' system libraries rather than a supertux bug then.
Back to the original issue, fixing the issue by just moving the #endif a bit further down to make all the locale initialization Win32-only is certainly an option, as I don't think we are using it for anything other than boost::filesystem::path::imbue(), which itself is only necessary for Win32 to begin with.
I think this is a reasonable solution, and if everyone's okay with it then I can submit a PR.
I am going to close this, since #1663 got merged.
SuperTux version: 15555065bbfd1e9f364bf1c86c6c2da8d37263fc System information: macOS 11.1, Apple M1/arm64
Expected behavior
Supertux runs
Actual behavior
Supertux crashes on startup
Steps to reproduce actual behavior
Build on macOS 11/arm64. Versions:
clang (Xcode):
Apple clang version 12.0.0 (clang-1200.0.32.28)
boost (brew):1.75.0
SDL2 (brew):2.0.14
The following patch stops the crashes, but according to a comment in the code relies on C++17 features (though on cppreference I'm seeing that the std::locale(string) construct was introduced in C++11, so I'm not sure exactly what part relies on C++17).
Additional debugging information
The following backtrace was recorded in lldb upon launching Supertux. Note the presence of libboost_locale functions at frame #2.