Closed berarma closed 6 months ago
Does this also happen when you run performous with the spanish language set within the settings? (you can change this setting runtime since 1.2.0 so there's no need to override LC_ALL
anymore
Does this also happen when you run performous with the spanish language set within the settings? (you can change this setting runtime since 1.2.0 so there's no need to override
LC_ALL
anymore
Yes, it's the same.
I'm only overriding LC_ALL
to test with C locale. My default locale is es_ES. I just wrote the steps to reproduce that way so that it could be reproduced in systems with English locales.
Thanks for the quick response, could you share your song.json file? Then we can take a look at it 👍
Of course. songs.json.gz
Thanks a lot! Since you mentioned the float with period and you're using the spanish locale... What happens if you replace all the periods with a comma?
It seems to me a problem on globalization.. We write with a period, but when reading we expect a comma (since that's how decimal values are written in spanish: 3,5
instead of 3.5
If I replace periods with commas then it works. I've also quoted the numbers to avoid issues with the Json format.
Then I've tried only adding the quotes to see which change worked and it was the quotes. Simply quoting (") the float numbers makes it work.
Then I tried just replacing periods with commas even though the resulting Json is invalid, and it works too.
And to add to the weirdness. it works when the cache file is less than ~500 entries long.
Hmmm then it's probably the comma/period thing combined with locale settings.
@HetorusNL last time you fixed UTF8 problem in master. Any idea how to write and read the json with the current locale?
A little more. I'm suspecting about some race condition so I've put a delay just before creating the Window object in the mainloop. With that delay there it can load the cache file. If I put the delay after the window creation it fails again. So it seems the window object is doing something that the Json code doesn't like.
I think I know what's happening. The initialization of the SDL video subsystem sets the locale using setlocale
and since it's running in parallel to the Json code it messes the parsing which uses strtof
. I've tested it without initializing the video subsystem, only the joystick, and it works. I've also found the code where the locale is set inside SDL: https://github.com/libsdl-org/SDL/blob/1b284cd4153d967f17cad9535cf00c153dd62570/src/video/x11/SDL_x11keyboard.c#L203
I don't know what's the best way to fix it. Could we make the loading of songs to run synchronously at least on Linux?
Really, it's only the loading of the Json which should be synchronous. That's really fast. I think it would be no problem.
Hmmm how about setting the locale before anything happens?, that's a best practice anyway this should fix the problem i guess?
Hmmm how about setting the locale before anything happens?, that's a best practice anyway this should fix the problem i guess?
We could set the locale ourselves before loading the file but this would only make the issue permanent, it would still have to be fixed. And I'm not sure there's a need to set the locale.
Maybe the root of the issue is outside this project, because why the Json library isn't locale independent when parsing and SDL needs to play with the locale in this way?
I've tried making the loading of the Json synchronous. It's only moving a few lines of code and it works well. I can make a PR.
Investigating a bit more, the json library depends on a non-changing locale for correctly parsing. A locale change while it's parsing will make it fail.
SDL needs to change temporarily the locale before calling a X11 function. The call will probably produce a context switch.
Thus, parsing a json file concurrently while initializing SDL isn't safe.
Performous & operating system versions
Performous 1.3.0-45-gcb10e1c6 (latest master) OS: Debian 12.2
What is the problem?
First run without cache files goes well. Next time Performous is run and tries to load the cache Json file it aborts. Running with command
LC_ALL=C ./performous
loads the cache file correctly.I've tried to analyze the issue and it's an assert related to the parsing of float values. Float values are written with dots but for some reason the json parser has issues parsing the dots.
What's weird is that it only happens when there's a certain amount of entries in the cache file. It seems to fail always when parsing around the 600-900th entry. I've checked it's not related to any particular entry. It seems to be related to the position of the entry in the cache file.
Steps to reproduce
LC_ALL=es_ES.utf8 ./performous
over a large directory of songs.LC_ALL=es_ES.utf8 ./performous
.Additional context
Backtrace:
Log(s) & preferences file(s)
No response