News:

SimuTranslator
Make Simutrans speak your language.

XML write problem - new MinGW setup

Started by TurfIt, February 04, 2010, 05:45:42 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

TurfIt

I recently setup MinGW and MSYS for compiling Simutrans. After the seemingly normal GNU grief getting it working I have a sim.exe. It runs great with every function I've tested so far working, right up until I exit the game. At this point it crashes with the every helpful "Simutrans has encountered a problem and needs to close" and it cannot be restarted again. I noticed the settings.xml file grew to ~20K and contained garbage after the crash. Deleting the corrupt file allows the game to start but it repeats the crash on closing.

I've virgin installed MinGW-5.1.6current, MSYS-1.0.11, svn-win32-1.6.2, wget-1.9.1-mingwPORT.tar.bz2, zlib-1.2.3-mingwPORT-1.tar.bz2, libpng-1.2.35.tar.bz2, and lzo-2.03.tar.gz in that order following the OpenTTD wiki instructions. OpenTTD now compiles/runs fine. Installed SDL-1.2.14.tar.gz. Checked out the Simutrans source, configured config.default for sdl, 16bpp, mingw, debug3, and ran make. Fixed the include/lib search paths (i.e. MinGW doesn't search /usr/local/{include,lib} by default). Fixed the missing cc.exe (more MinGW weirdness). Ran make again and sim.exe produced.

Setting the savefile format to xml also results in a crash while saving. xml savefiles produced with stable 102.2.1 can be loaded ok. settings.xml written by 102.2.1 is also loaded ok by my .exe. Nightly 3055 also works. I've tried compiling 3072, 3075, and 3055 all with the same result; Although the size of settings.xml varies greatly based upon which version I use - ~4K > ~20K. Changing the settings.xml saveformat to loadsave_t::zipped in simmain.cc allows me to quit without crashing.

Something appears to be going very wrong in the rdwr_xml_number() function when compiled on my system. I have absolutely no idea what could possibly be wrong to cause this behavior. Does anybody have any ideas? Anyone actually use MinGW?

Attached settings.xml (.txt added to allow attachment) is from 3075 with debug not set.

Dwachs

Does it help to change line 546 in dataobj/loadsave.cc to

size_t len = sprintf( nr, "%*s<%s>%.0f</%s>\n", ident, "", typ, (double)s, typ );

ie remove the 'l' modifier in %.0lf  ?
Parsley, sage, rosemary, and maggikraut.

prissi

#2
Did you do a make clean after unsuccessful compiling? It seems to me the ouput routine is completely broken, i.e. the wrong include/lib is used.

For MinGW you MUST NOT use the lib pathes from MSVC if present. The usual MSYS installer does nearly everything right. IF you downloaded/installed the packages with port, you should not need to alter any paths by hand.

(ON a sidenote: for developing/debugging on Windows, I strongly recommend MS Visual C++ express (which is free) and has a real debugger integrated into it. GDB is really uncomfortable to use on a command line )

EDIT: looking at your xml-file, it seems like enstellungen was actuall a NULL pointer.

TurfIt

#3
Quote from: prissi on February 04, 2010, 12:53:13 PM
Did you do a make clean after unsuccessful compiling? It seems to me the ouput routine is completely broken, i.e. the wrong include/lib is used.

Make clean has been used... Also, the whole development environment and been wiped and reinstalled many times. The XML output routine appears to be using nothing but standard libraries. It seems unlikely to me that using the wrong includes/lib would make it cleanly through the make, and then exhibit this runtime behavior.


Quote from: prissi on February 04, 2010, 12:53:13 PM
For MinGW you MUST NOT use the lib pathes from MSVC if present. The usual MSYS installer does nearly everything right. IF you downloaded/installed the packages with port, you should not need to alter any paths by hand.

MSVC is not, and has never been installed. I have finally installed MinGW/MSYS such that /usr/local/{include,lib} are no longer used. No more path altering. MinGW also had a new release last night, no difference to the crash.
My original install had libpng, bzip2, and SDL compiled from source rather than the mingwPORT versions. Now using the ports - no difference.


Quote from: prissi on February 04, 2010, 12:53:13 PM
(ON a sidenote: for developing/debugging on Windows, I strongly recommend MS Visual C++ express (which is free) and has a real debugger integrated into it. GDB is really uncomfortable to use on a command line )

I've been trying to avoid installing more MS bloat... Hence banging my head on the wall for a week in GNU land. If I have to...


Quote from: prissi on February 04, 2010, 12:53:13 PM
EDIT: looking at your xml-file, it seems like enstellungen was actuall a NULL pointer.

If einstellungen was NULL, wouldn't it still be null when I compile using loadsave_t::zipped for the settings.xml format?


Quote from: Dwachs on February 04, 2010, 07:16:18 AM
Does it help to change line 546 in dataobj/loadsave.cc to

size_t len = sprintf( nr, "%*s<%s>%.0f</%s>\n", ident, "", typ, (double)s, typ );

ie remove the 'l' modifier in %.0lf  ?

Now this fixes it! A quick googling turns up:
http://old.nabble.com/lf-format-issue-td21852952.html
which states MinGW since 3.15 interprets %lf as %Lf and tries to feed an 80 bit long double to msvcrt.dll which can only handle 64 bits >>> crash. (msvcrt.dll is listed as the ModName in the windows crash dialog)


Quote from: old.nabble
> I have changed all of my formats to %f
That's sensible anyway; `%lf' is non-standard, non-portable and might well be described as a coding error

So, should the Simutrans source be purged of all references to %lf? A quick search reveals only two locations - the one above and: simwerkz.cc:1470

sprintf(toolstr, "%s, %ld$ (%.2lf$), %dkm/h",


Appears to be something to do with a tooltip, but I can't find it in game to see if its display also triggers my crash.

EDIT: it's the tooltip displaying the way information in the tools. No crash. Bad display "Low quality track, 30c (0.00c), 5848866km/h" !

Dwachs

thank you for this investigation. Should be fixed in rev 3080.
Parsley, sage, rosemary, and maggikraut.

prissi

#5
I am very curious why this does not happen on any mingw compiled binaries I produced over the year. Imho this is a bug in MinGW due to at least two reasons:

- it is against POSIX (which states that printf %xyz should be possible also as scanf; even more sscanf requires %lf for doubles ...

-it breaks tons of old code

- before ANSI C you had even to use %lf or your programm crashes, since in those days no parameter lists were available and I know at least one compiler who puts floats as 32bit and doubles as 64bits on the stack.

happy()
float a;
char *p;
{
if(*p==0)
...
}

happy( (double)0.0, "a" );

=> crash when accessing *p (try it on a K&R compiler) Since ANSI is backward, it should do the same imho.

EDIT:
Since the first four float/double/long double are passed via registers in MSVC-code (http://msdn.microsoft.com/de-de/library/dd2wa36c.aspx), even though a 80bit int is passes, it should not matter. Also I am not sure, why then everything is zero. Even long doubles are passed via registers. And of course Windows NT is a POSIX complient system, so it handles %lf as it should, when I checked it.

EDIT2:
After more googling: it seems the guys at mingw used an error in the documentation (most likely %llf for long with a forgotten l) to change their printf implementation to match an printf, which never works as documented and are too stupid to believe that they do not need to adhere to ISO C99 standard and break code that runs under MSVC compilers. (Where is the head bashing smily gone?)

wernieman

Wich mingw version?

At example I use for the nightlys:
mingw-runtime-3.16
I hope you understand my English

prissi

#7
This stupid behaviour was aparently introduced in ming 3-15.

Aparently the stable version (which is from 2006) works flawlessly:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
double d=123456.7778823570312840;
printf( "%.20f\n", d );
printf( "%.20lf\n", d );
printf( "%.20llf\n", d );
printf( "%.20Lf\n", d );
return 0;
}

Even %Lf is ignored (or, since the parameters are passed via floating point registers are automatically correct, since those are anyway 80 bits). This works under MinGW 5.1.6 an XP I just checked it. Could you check this too for your setup?

So these guys are simply wrong about the microsoft library. And I use stable release for compiling which is GCC 3.4.5. It seems that the newer "proposed" versions are broken. Unfourtunately the new file relase system makes it really hard to get the stable for newbies.

Breaking ISO C99 and POSIX to duplicate a bug in the MSDN documentation which was not implemented in the original microsoft code; not to mention to break tons of other software: These are really great guys with deep understanding.

I think I will enter an #error to annoy people compiling on MinGW newer version for now. MSVC is better for newbies, it is nowadays a single click install apart from bzlib.h, but easier than MinGW. Programming against ISO C99 is really stupid.

Spike

I'm puzzled. I'd not have expected an open source tool trying to mimick a flaw in the MS libraries ... the world has gone bad :(

TurfIt

Quote from: Dwachs on February 05, 2010, 06:24:02 AM
thank you for this investigation. Should be fixed in rev 3080.

Looks to be. I can't find any more than those two references to %lf.


Quote from: wernieman on February 05, 2010, 10:52:20 AM
Wich mingw version?

Version details are in my first post. However using the 5.1.6 installer means the specific package versions change even when you select the same option - current.



On Feb 2 it gave:
runtime=mingwrt-3.15.2-mingw32-dev.tar.gz
w32api=w32api-3.13-mingw32-dev.tar.gz
binutils=binutils-2.19.1-mingw32-bin.tar.gz
core=gcc-core-3.4.5-20060117-3.tar.gz
gpp=gcc-g++-3.4.5-20060117-3.tar.gz
runtimeDLL=mingwrt-3.15.2-mingw32-dll.tar.gz   

On Feb 4 it gave:
runtime=mingwrt-3.17-mingw32-dev.tar.gz
w32api=w32api-3.14-mingw32-dev.tar.gz
binutils=binutils-2.20-1-mingw32-bin.tar.gz
core=gcc-core-3.4.5-20060117-3.tar.gz
gpp=gcc-g++-3.4.5-20060117-3.tar.gz
runtimeDLL=mingwrt-3.17-mingw32-dll.tar.gz

Both have the problem.


Quote from: prissi on February 05, 2010, 02:11:44 PM
Aparently the stable version (which is from 2006) works flawlessly:

What specific packages are you calling stable?


Quote from: prissi on February 05, 2010, 02:11:44 PM
This works under MinGW 5.1.6 an XP I just checked it. Could you check this too for your setup?

Works fine. Produces:
123456.77788235703000000000
123456.77788235703000000000
123456.77788235703000000000
123456.77788235703000000000
with no crash.


Quote from: Hajo on February 05, 2010, 02:14:36 PM
I'm puzzled. I'd not have expected an open source tool trying to mimick a flaw in the MS libraries ... the world has gone bad :(

Indeed!

wernieman

@prissi
so I must use for the nightlys the Version bevor 3.15??

Then I get a Problem, because Gentoo only knows Version after 3.15.2. ..... and I must Install it "per Hand" ...

I hope you understand my English

prissi

Not sure, maybe "-posix" switch helps, since posix requires to ignore the "lf" flag. And it is removed anyway in current nightly.

wernieman

I hope you understand my English

Dwachs

should be fixed anyway. you dont have to change your compiling equipmetn. ;)
Parsley, sage, rosemary, and maggikraut.