News:

Use the "Forum Search"
It may help you to find anything in the forum ;).

Segmentation fault in money_to_string function

Started by Roboron, January 03, 2022, 08:22:11 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Roboron

Trying to build and run Simutrans 123 on Ubuntu 20.04 LTS VM, I'm getting segfault when running the game (just at the end of the loading screen). Running debug build in GDB gave me this:

Thread 1 "simutrans" received signal SIGSEGV, Segmentation fault.
0x0000555555a283e9 in money_to_string (
    p=0x7ffffffff001 <error: No se puede acceder a la memoria en la dirección 0x7ffffffff001>,
    f=200000, show_decimal=true) at /home/rober/Documentos/trunk/utils/simstring.cc:109
109        *p++ = tp[i++];


("No se puede acceder a la memoria en la dirección #" =  cannot access memory address #)

=> https://github.com/aburch/simutrans/blob/master/utils/simstring.cc#L109

A check is missing somewhere?

prissi

This is shows at the bottom of the screen, in the player dialog and the finance window. However, I suspect a broken or missing translation file is the most likely cause. Otherwise the nubmer would have to be extremely large (larger than 10^100)

Roboron

It's a clean install, I have not modified any file. On my main machine I can't reproduce this, not even if I delete my simutrans folder and start fresh. May it be something related to the virtual machine?

cocobean

#3
Ref: https://github.com/haikuports/haikuports/issues/6556

We had this issue over at haiku-os.org with Simutrans. A user found that it was a locale setting issue during starup.

"With english set as the main language and german formatting the game runs. Setting german (or non-English) to be the only language in the settings and leaving the locale as english - crashes the game."

Possibly a locale bug in either a settings file or code loading the translations.... see the dev team....

If env global system settings are 'LC_*=en.UTF-8'
'simutrans -lang es' may work as a workaround. This works on my system for all alternative languages during game startup..

_Hajo_

I think this here is the weak point in the function


// format string
l = (long)(size_t)(strchr(tp,'.') - tp);


It assumes that there is a dot in the number string. If the sprintf function of the c library of the system uses locale settings to find out what character to use for a decimal dot, and this is not a dot for the current locale, scanning for the dot will fail

The rest of the function looks safe to me - well, it does no checks on the buffer that is supplied to store the number, but that should not be OS dependent.

The crash happens a few lines later, when the value of l is taken in account to place a thousands separators.

Dwachs

Seems to be the case. Strange that all the documentation pages on printf never mention locales, while the pages about locales mention that these settings might influence printf :/
Parsley, sage, rosemary, and maggikraut.

prissi

#6
This will crash a huge amount of other programs assuming printf always returning a dot a decimal separator. Well

setlocale(LC_NUMERIC, "en_US.UTF-8");

in main() hopefully should take care of that ...

That may be also the reason why it started on all emulators in Android but not on my actual device (which was set to german). I had then suspected it was just too old ...

The documentation say also "implementation defined", so it may happen or not?!?

Ters

I've recently been having problems with something similar, although it was expected that the printf-like function used the locale specific symbols, and the locale the program ran with was fixed. What wasn't expected, was that which symbols were used for that specific locale changed. More specifically, the codepoint used to prefix negative numbers changed from U+002D to U+2212. A proper minus sure looked better, and is typographically correct, but caused compatibility problems with other things, like copying the number into Excel. (A bigger problem was however that the function which parses text into numbers only accepted U+2212 for minus, and there is no key for that on any keyboard that gives that codepoint with any keyboard mapping in common use.)