[Freeciv-Dev] Server hangs on an Alpha
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
I searched the bug tracking system and the mailing list archives so I
apologize if this has come up before, but I don't believe it has.
The Setup:
Running Alpha Linux Redhat 6.0 with glibc 2.1.1-7 and egcs 2.91.66.
int is 32-bit, long is 64-bit, long long is 64-bit, pointers are 64-bit
The Software:
Freeciv 1.8.0, FreeCiv 1.8.1 and FreeCiv CVS (Wed Jul 28 1999)
Compilation Flags:
All code was compiled with "-O0 -ggdb" no optimization was used.
The Bug:
When you set the "generator" option to any value other than 1 the
server hangs. (Note: this bug is present on an Alpha, Intel-like
machines work just fine)
These exact steps will cause the server to hang for me:
set generator 2
create ai
start
-- server hangs
Also "set generator 3" and "set generator 4" will cause the server
to hang.
Why I think it hangs:
Lines numbers are with respect to FreeCiv 1.8.1.
In the fillisland() function at line 989 of mapgen.c there is the
following code:
while (i && failsafe--) {
On an Intel-like machine the value of "i" is usually less than 100
and failsafe is in the tens of thousands. On the Alpha (using a
generator greater than 1) the value of "i" is in the tens of
millions as is failsafe. So in fact the server hangs b/c it is
in this while loop for a *really* long time.
The fact that failsafe is so big is because in fillisland() at
line 983 of mapgen.c it is shown that failsafe is dependent on "i".
In turn at line 978 of mapgen.c (in fillisland()) we see the following
code:
i = *bucket / capac;
So "i" is dependent on bucket (which is an int* passed into
fillisland()) and capac. Stepping through this code in GDB we find
that capac always has reasonable values, but *bucket is extremely
high. Thus "i" is extremely big because *bucket is extremely big.
Now the function that is calling fillisland() is makeisland().
Inside of makeisland() we see at lines 1141 to lines 1145 of
mapgen.c that the variables riverbuck, mountbuck, desertbuck,
forestbuck and swampbuck are set to random values.
Now also notice that inside makeisland() we are calling
fillisland() several different times. Each time passing in the
address of one of the *buck variables that I mentioned above.
Well these *buck variables are what the "*bucket" variable inside of
fillisland() really is. So the fact that "*bucket" is so large is
b/c these *buck variables are so large.
Now on a Intel-like machine the *buck variables always seem to be
less than 1000 and negative. On the Alpha they are positive and in
the tens of millions.
It almost seems as though these variables are never getting
set...well we notice that initialization of these variables in
contingent on an if-statement in makeisland() at line 1126. The line
reads:
if (!islemass) {
Well the 1st time makeisland() is called islemass is 0, so we enter
in the then-block of the if-statement. Now this is were the
weirdness happens. I reproduce the then-block of the above
if-statement so I can refer to it easily:
Line 1126 if (!islemass) {
Line 1127 /* setup initial static parameters */
Line 1128 balance = 0;
Line 1129 isleindex = 3; /* 0= none, 1= arctic, 2= antarctic */
Line 1130
Line 1131 checkmass= totalmass;
Line 1132
Line 1133 /* caveat: this should really be sent to all players */
Line 1134 if(totalmass>3000)
Line 1135 freelog(LOG_NORMAL,"high landmass - this may take a few
seconds");
Line 1136
Line 1137 i = map.riverlength + map.mountains
Line 1138 + map.deserts + map.forestsize + map.swampsize;
Line 1139 i = i <= 90 ? 100 : i * 11 / 10;
Line 1140 tilefactor = totalmass / i;
Line 1141 riverbuck = -myrand(totalmass);
Line 1142 mountbuck = -myrand(totalmass);
Line 1143 desertbuck = -myrand(totalmass);
Line 1144 forestbuck = -myrand(totalmass);
Line 1145 swampbuck = -myrand(totalmass);
Line 1146 lastplaced = totalmass;
Line 1147 } else {
Now on the 1st call to makeisland() islemass is zero. We go through
lines 1127 to 1140 just fine. Then at line 1141 we "magically" go
back to the beginning of makeisland(). Now remember, I compiled
with -O0. There is no code optimization going on.
I can't say for sure what is happening. Anyway that is about as far
as I got before I had to give up. I did try replacing myrand() and
mysrand() w/ direct calls to rand() and srand() thinking there might
have been an issue w/ the PRNG code, but it didn't fix anything.
So a quick summary of why the program hangs:
The program hangs because it goes into several really long while()
loops.
The loops are really long because "i" and "failsafe" in fillisland()
are really big.
Failsafe is big because "i" is big and "i" is big because bucket is big
bucket is big because the *buck variables in makeisland() are big.
The *buck variables are big because they are never initialized
The variables are never initialized because of a magic code jump
right whey they are about to be set.
I don't know why the magic code jump happens, I compiled with -O0.
Perhaps a egcs bug?
Anyway that is all the information I have. If anybody can provide
some more input or lists of things to try then I would appreciate it.
If it is a bug in egcs then I am at a complete loss as to how to verify
it as such. The only time I have ever seen "magic code jumps" is when I am
debugging optimized code.
Thanks for your time.
- [Freeciv-Dev] Server hangs on an Alpha,
Matthew OConnor <=
- [Freeciv-Dev] Server hangs on an Alpha, Nicolas Brunel, 1999/07/28
- Re: [Freeciv-Dev] Server hangs on an Alpha, Nicolas Brunel, 1999/07/28
- Re: [Freeciv-Dev] Server hangs on an Alpha, Matthew OConnor, 1999/07/28
- Re: [Freeciv-Dev] Server hangs on an Alpha, Nicolas Brunel, 1999/07/28
- Re: [Freeciv-Dev] Server hangs on an Alpha, Rizos Sakellariou, 1999/07/29
- Re: [Freeciv-Dev] Server hangs on an Alpha, Matthew OConnor, 1999/07/29
- Re: [Freeciv-Dev] Server hangs on an Alpha, Nicolas Brunel, 1999/07/29
- Re: [Freeciv-Dev] Server hangs on an Alpha, David Pfitzner, 1999/07/29
|
|