[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] gcc4 vs gcc2 crash "test case"



Some news about Quake:

1) Warnings. When compiling Quake with GCC 4.2.2, a lot of warnings are issued. It is a problem because it might hide a serious issue. I fixed all of them, there was nothing serious (only missing casts, or something like that). Now the build is clean.

2) Memory problem. When I run Quake without any option, it crashes because there is not enough memory. The reason of the crash is that the malloc return value is not tested. Very bad, especially for a huge value that have good chances to fail ! I added a check in main() in sys_atari.c:
	parms.membase = malloc (parms.memsize);
	if (!parms.membase)
	{
		fprintf(stderr, "Error: not enough memory\n");
		exit(1);
	}
Then I can run Quake with the option "-mem 10". The error message is displayed if the value is too high.

3) Alignment. Sometimes, Quake complains about "Globals are missaligned". This is because the test variable is not aligned on a 32-bit boundary. It might not be a problem (except for performance issues), I disabled the tests in R_RenderView() in r_main.c

4) Special care must be taken for cross-compiling Quake. The file quakedef68k.i contains defines for structure offsets to be used in the assembly sources. That file is generated with the gendefs tool. However, that tool uses the offset values from the build host, no the ones of the target ! Because the structure alignment is different between Cygwin and MiNT, the produced executable is wrong and it fails while loading the files. It is still possible to cross-compile Quake by disabling the generation of quakedef68k.i and by using the one produced by a native build of gendefs.c. I spent a lot of time on that bug, because I thank it was the original problem ! Now cross-compilation produces the same result as the native compilation with GCC 4.

5) floor() problem. Sometimes Quake fails with "Bad surface extents". The problem is in CalcSurfaceExtents() in model.c. floor() and ceil() are called with values very close to an integer. But sometimes, because of errors with float round ups, floor() does not produce the obvious result ! For example (taken from Wikipedia), floor(0.6 / 0.2) produces 2.0, because in float representation 0.6 / 0.2 = something like 2.99999999999990, so the floor is 2 (the obvious result would be 3) ! The classic way to fix that issues is to call ceil() and floor() by adding an epsilon value in order to compensate the precision problem. I used that:
		bmins[i] = floor((mins[i]/16)+0.000001);
		bmaxs[i] = ceil((maxs[i]/16)-0.000001);
The weird thing is that the precision problem is not exactly the same when using different optimization options.

6) The real problem: after loading all the files, Quake fails with Bus Error, pc=0x3ff80000. It fails when compiled with GCC 4.2.2 (either cross or native) with -m68020-60 and -O1. However it works without optimization. I haven't found the cause of that bug yet.


So far, a lot of time spent, a lot of issues found, but not the real one. I continue the investigation.

--
Vincent Rivière