Windows bug fixes

This commit is contained in:
Perttu Ahola 2010-11-29 17:55:07 +02:00
parent d2090a32d8
commit d10627a77f
13 changed files with 162 additions and 90 deletions

@ -21,8 +21,8 @@ CXXFLAGS = -O2 -ffast-math -Wall -g -pipe
#CXXFLAGS = -O3 -ffast-math -Wall -g #CXXFLAGS = -O3 -ffast-math -Wall -g
#CXXFLAGS = -O2 -ffast-math -Wall -g #CXXFLAGS = -O2 -ffast-math -Wall -g
#FASTCXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 FASTCXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686
FASTCXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 -fwhole-program #FASTCXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 -fwhole-program
#Default target #Default target
@ -53,9 +53,9 @@ all_linux all_win32: $(DESTPATH)
fast_linux: $(FASTDESTPATH) fast_linux: $(FASTDESTPATH)
$(FASTDESTPATH): $(SOURCES) $(FASTDESTPATH): $(SOURCES)
@#$(CXX) -o $(FASTDESTPATH) $(SOURCES) $(CPPFLAGS) $(FASTCXXFLAGS) $(LDFLAGS) -DUNITTEST_DISABLE $(CXX) -o $(FASTDESTPATH) $(SOURCES) $(CPPFLAGS) $(FASTCXXFLAGS) $(LDFLAGS) -DUNITTEST_DISABLE
@# Errno doesn't work ("error: __errno_location was not declared in this scope") @# Errno doesn't work ("error: __errno_location was not declared in this scope")
cat $(SOURCES) | $(CXX) -o $(FASTDESTPATH) -x c++ - -Isrc/ $(CPPFLAGS) $(FASTCXXFLAGS) $(LDFLAGS) -DUNITTEST_DISABLE -DDISABLE_ERRNO @#cat $(SOURCES) | $(CXX) -o $(FASTDESTPATH) -x c++ - -Isrc/ $(CPPFLAGS) $(FASTCXXFLAGS) $(LDFLAGS) -DUNITTEST_DISABLE -DDISABLE_ERRNO
$(DESTPATH): $(OBJECTS) $(DESTPATH): $(OBJECTS)
$(CXX) -o $@ $(OBJECTS) $(LDFLAGS) $(CXX) -o $@ $(OBJECTS) $(LDFLAGS)

@ -41,6 +41,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include";"..\jthread\jthread-1.2.1\src";"..\irrlicht\irrlicht-1.7.1\include"" AdditionalIncludeDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include";"..\jthread\jthread-1.2.1\src";"..\irrlicht\irrlicht-1.7.1\include""
PreprocessorDefinitions="WIN32" PreprocessorDefinitions="WIN32"
BufferSecurityCheck="true"
EnableEnhancedInstructionSet="1" EnableEnhancedInstructionSet="1"
FloatingPointModel="2" FloatingPointModel="2"
DebugInformationFormat="1" DebugInformationFormat="1"
@ -117,10 +118,11 @@
OmitFramePointers="true" OmitFramePointers="true"
WholeProgramOptimization="true" WholeProgramOptimization="true"
AdditionalIncludeDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include";"..\jthread\jthread-1.2.1\src";"..\irrlicht\irrlicht-1.7.1\include"" AdditionalIncludeDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include";"..\jthread\jthread-1.2.1\src";"..\irrlicht\irrlicht-1.7.1\include""
PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE" PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE,_CRT_SECURE_NO_DEPRECATE"
BufferSecurityCheck="false" BufferSecurityCheck="false"
EnableEnhancedInstructionSet="1" EnableEnhancedInstructionSet="1"
FloatingPointModel="2" FloatingPointModel="2"
DebugInformationFormat="0"
/> />
<Tool <Tool
Name="VCManagedResourceCompilerTool" Name="VCManagedResourceCompilerTool"
@ -135,6 +137,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalLibraryDirectories="&quot;C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib&quot;;&quot;..\jthread\jthread-1.2.1\Release&quot;;&quot;..\irrlicht\irrlicht-1.7.1\lib\Win32-visualstudio&quot;" AdditionalLibraryDirectories="&quot;C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib&quot;;&quot;..\jthread\jthread-1.2.1\Release&quot;;&quot;..\irrlicht\irrlicht-1.7.1\lib\Win32-visualstudio&quot;"
IgnoreDefaultLibraryNames="libcmtd.lib" IgnoreDefaultLibraryNames="libcmtd.lib"
GenerateDebugInformation="false"
LinkTimeCodeGeneration="1" LinkTimeCodeGeneration="1"
/> />
<Tool <Tool

@ -56,8 +56,9 @@
// The distance of how far objects will be sent to client // The distance of how far objects will be sent to client
//#define ACTIVE_OBJECT_D_BLOCKS 2 //#define ACTIVE_OBJECT_D_BLOCKS 2
// Wether to catch all std::exceptions // Wether to catch all std::exceptions.
#define CATCH_UNHANDLED_EXCEPTIONS 0 // Assert will be called on such an event.
#define CATCH_UNHANDLED_EXCEPTIONS 1
/* /*
Collecting active blocks is stopped after object data Collecting active blocks is stopped after object data

@ -84,7 +84,7 @@ DebugStack::DebugStack(threadid_t id)
void DebugStack::print(FILE *file, bool everything) void DebugStack::print(FILE *file, bool everything)
{ {
fprintf(file, "BEGIN STACK: Debug stack for thread %x:\n", fprintf(file, "DEBUG STACK FOR THREAD %x:\n",
(unsigned int)threadid); (unsigned int)threadid);
for(int i=0; i<stack_max_i; i++) for(int i=0; i<stack_max_i; i++)
@ -92,11 +92,10 @@ void DebugStack::print(FILE *file, bool everything)
if(i == stack_i && everything == false) if(i == stack_i && everything == false)
continue; continue;
if(everything == true && i == stack_i) if(i < stack_i)
fprintf(file, "END OF STACK.\n"
"! Continuing beyond stack end:\n");
fprintf(file, "#%d %s\n", i, stack[i]); fprintf(file, "#%d %s\n", i, stack[i]);
else
fprintf(file, "(Leftover data: #%d %s)\n", i, stack[i]);
} }
if(stack_i == DEBUG_STACK_SIZE) if(stack_i == DEBUG_STACK_SIZE)

@ -474,6 +474,18 @@ public:
dstream<<DTIME<<"Enabled full viewing range"<<std::endl; dstream<<DTIME<<"Enabled full viewing range"<<std::endl;
} }
} }
// Print debug stacks
if(event.KeyInput.Key == irr::KEY_KEY_P
&& g_game_focused)
{
dstream<<"-----------------------------------------"
<<std::endl;
dstream<<DTIME<<"Printing debug stacks:"<<std::endl;
dstream<<"-----------------------------------------"
<<std::endl;
debug_stacks_print();
}
} }
} }
@ -2213,7 +2225,7 @@ int main(int argc, char *argv[])
{ {
dstream<<DTIME<<"Connection timed out."<<std::endl; dstream<<DTIME<<"Connection timed out."<<std::endl;
} }
#if CATCH_EXCEPTIONS #if CATCH_UNHANDLED_EXCEPTIONS
/* /*
This is what has to be done in every thread to get suitable debug info This is what has to be done in every thread to get suitable debug info
*/ */

@ -1522,7 +1522,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
*/ */
if(m_params.ravines_amount != 0) if(m_params.ravines_amount != 0)
{ {
if(rand()%(s32)(10.0 / m_params.ravines_amount) == 0) if(rand()%(s32)(20.0 / m_params.ravines_amount) == 0)
{ {
s16 s = 6; s16 s = 6;
s16 x = rand()%(MAP_BLOCKSIZE-s*2-1)+s; s16 x = rand()%(MAP_BLOCKSIZE-s*2-1)+s;
@ -1662,8 +1662,16 @@ MapBlock * ServerMap::emergeBlock(
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++) for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
{ {
//dstream<<"emergeBlock: x0="<<x0<<", z0="<<z0<<std::endl; //dstream<<"emergeBlock: x0="<<x0<<", z0="<<z0<<std::endl;
float surface_y_f = sector->getGroundHeight(v2s16(x0,z0)); float surface_y_f = sector->getGroundHeight(v2s16(x0,z0));
assert(surface_y_f > GROUNDHEIGHT_VALID_MINVALUE); //assert(surface_y_f > GROUNDHEIGHT_VALID_MINVALUE);
if(surface_y_f < GROUNDHEIGHT_VALID_MINVALUE)
{
dstream<<"WARNING: Surface height not found in sector "
"for block that is being emerged"<<std::endl;
surface_y_f = 0.0;
}
s16 surface_y = surface_y_f; s16 surface_y = surface_y_f;
//avg_ground_y += surface_y; //avg_ground_y += surface_y;
if(surface_y < lowest_ground_y) if(surface_y < lowest_ground_y)
@ -2452,6 +2460,9 @@ void ServerMap::saveBlock(MapBlock *block)
void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSector *sector) void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSector *sector)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
try{
// Block file is map/sectors/xxxxxxxx/xxxx // Block file is map/sectors/xxxxxxxx/xxxx
std::string fullpath = m_savedir+"/sectors/"+sectordir+"/"+blockfile; std::string fullpath = m_savedir+"/sectors/"+sectordir+"/"+blockfile;
std::ifstream is(fullpath.c_str(), std::ios_base::binary); std::ifstream is(fullpath.c_str(), std::ios_base::binary);
@ -2484,6 +2495,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
created_new = true; created_new = true;
} }
// deserialize block data
block->deSerialize(is, version); block->deSerialize(is, version);
/* /*
@ -2509,6 +2521,14 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
// We just loaded it from the disk, so it's up-to-date. // We just loaded it from the disk, so it's up-to-date.
block->resetChangedFlag(); block->resetChangedFlag();
}
catch(SerializationError &e)
{
dstream<<"WARNING: Invalid block data on disk "
"(SerializationError). Ignoring."
<<std::endl;
}
} }
// Gets from master heightmap // Gets from master heightmap

@ -106,6 +106,7 @@ public:
void cacheCreated() void cacheCreated()
{ {
dstream<<"cacheCreated() begin"<<std::endl;
JMutexAutoLock waitcachelock(m_waitcache_mutex); JMutexAutoLock waitcachelock(m_waitcache_mutex);
JMutexAutoLock countlock(m_count_mutex); JMutexAutoLock countlock(m_count_mutex);
@ -114,10 +115,13 @@ public:
m_cache_mutex.Lock(); m_cache_mutex.Lock();
m_count++; m_count++;
dstream<<"cacheCreated() end"<<std::endl;
} }
void cacheRemoved() void cacheRemoved()
{ {
dstream<<"cacheRemoved() begin"<<std::endl;
JMutexAutoLock countlock(m_count_mutex); JMutexAutoLock countlock(m_count_mutex);
assert(m_count > 0); assert(m_count > 0);
@ -127,6 +131,8 @@ public:
// If this is the last one, release the cache lock // If this is the last one, release the cache lock
if(m_count == 0) if(m_count == 0)
m_cache_mutex.Unlock(); m_cache_mutex.Unlock();
dstream<<"cacheRemoved() end"<<std::endl;
} }
/* /*
@ -137,8 +143,11 @@ public:
*/ */
JMutexAutoLock * waitCaches() JMutexAutoLock * waitCaches()
{ {
dstream<<"waitCaches() begin"<<std::endl;
JMutexAutoLock waitcachelock(m_waitcache_mutex); JMutexAutoLock waitcachelock(m_waitcache_mutex);
return new JMutexAutoLock(m_cache_mutex); JMutexAutoLock *lock = new JMutexAutoLock(m_cache_mutex);
dstream<<"waitCaches() end"<<std::endl;
return lock;
} }
private: private:

@ -356,9 +356,10 @@ public:
// This is a "Standard MeshBuffer", // This is a "Standard MeshBuffer",
// it's a typedeffed CMeshBuffer<video::S3DVertex> // it's a typedeffed CMeshBuffer<video::S3DVertex>
scene::IMeshBuffer *buf = new scene::SMeshBuffer(); scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// Set material // Set material
((scene::SMeshBuffer*)buf)->Material = p.material; buf->Material = p.material;
//((scene::SMeshBuffer*)buf)->Material = p.material;
// Use VBO // Use VBO
//buf->setHardwareMappingHint(scene::EHM_STATIC); //buf->setHardwareMappingHint(scene::EHM_STATIC);
// Add to mesh // Add to mesh

@ -33,7 +33,15 @@ void MapBlockObject::setBlockChanged()
*/ */
void MovingObject::move(float dtime, v3f acceleration) void MovingObject::move(float dtime, v3f acceleration)
{ {
//m_pos += dtime * 3.0; DSTACK("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
", dtime=%f, acc=(%f,%f,%f)",
__FUNCTION_NAME,
getTypeId(),
m_pos.X, m_pos.Y, m_pos.Z,
m_speed.X, m_speed.Y, m_speed.Z,
dtime,
acceleration.X, acceleration.Y, acceleration.Z
);
v3s16 oldpos_i = floatToInt(m_pos); v3s16 oldpos_i = floatToInt(m_pos);
@ -51,6 +59,16 @@ void MovingObject::move(float dtime, v3f acceleration)
return; return;
} }
// Set insane speed to zero
// Otherwise there will be divides by zero and other silly stuff
if(m_speed.getLength() > 1000.0*BS)
m_speed = v3f(0,0,0);
// Limit speed to a reasonable value
float speed_limit = 20.0*BS;
if(m_speed.getLength() > speed_limit)
m_speed = m_speed * (speed_limit / m_speed.getLength());
v3f position = m_pos; v3f position = m_pos;
v3f oldpos = position; v3f oldpos = position;
@ -471,16 +489,24 @@ MapBlockObject * MapBlockObjectList::get(s16 id)
void MapBlockObjectList::step(float dtime, bool server) void MapBlockObjectList::step(float dtime, bool server)
{ {
DSTACK(__FUNCTION_NAME);
JMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<s16, bool> ids_to_delete; core::map<s16, bool> ids_to_delete;
{
DSTACK("%s: stepping objects", __FUNCTION_NAME);
for(core::map<s16, MapBlockObject*>::Iterator for(core::map<s16, MapBlockObject*>::Iterator
i = m_objects.getIterator(); i = m_objects.getIterator();
i.atEnd() == false; i++) i.atEnd() == false; i++)
{ {
MapBlockObject *obj = i.getNode()->getValue(); MapBlockObject *obj = i.getNode()->getValue();
DSTACK("%s: stepping object type %i", __FUNCTION_NAME,
obj->getTypeId());
if(server) if(server)
{ {
bool to_delete = obj->serverStep(dtime); bool to_delete = obj->serverStep(dtime);
@ -493,6 +519,10 @@ void MapBlockObjectList::step(float dtime, bool server)
obj->clientStep(dtime); obj->clientStep(dtime);
} }
} }
}
{
DSTACK("%s: deleting objects", __FUNCTION_NAME);
// Delete objects in delete queue // Delete objects in delete queue
for(core::map<s16, bool>::Iterator for(core::map<s16, bool>::Iterator
@ -506,6 +536,7 @@ void MapBlockObjectList::step(float dtime, bool server)
delete obj; delete obj;
m_objects.remove(id); m_objects.remove(id);
} }
}
/* /*
Wrap objects on server Wrap objects on server
@ -514,6 +545,9 @@ void MapBlockObjectList::step(float dtime, bool server)
if(server == false) if(server == false)
return; return;
{
DSTACK("%s: object wrap loop", __FUNCTION_NAME);
for(core::map<s16, MapBlockObject*>::Iterator for(core::map<s16, MapBlockObject*>::Iterator
i = m_objects.getIterator(); i = m_objects.getIterator();
i.atEnd() == false; i++) i.atEnd() == false; i++)
@ -539,10 +573,13 @@ void MapBlockObjectList::step(float dtime, bool server)
// Restart find // Restart find
i = m_objects.getIterator(); i = m_objects.getIterator();
} }
}
} }
bool MapBlockObjectList::wrapObject(MapBlockObject *object) bool MapBlockObjectList::wrapObject(MapBlockObject *object)
{ {
DSTACK(__FUNCTION_NAME);
// No lock here; this is called so that the lock is already locked. // No lock here; this is called so that the lock is already locked.
//JMutexAutoLock lock(m_mutex); //JMutexAutoLock lock(m_mutex);

@ -11,6 +11,7 @@
#include "serialization.h" #include "serialization.h"
#include "mapnode.h" #include "mapnode.h"
#include "constants.h" #include "constants.h"
#include "debug.h"
enum enum
{ {

@ -670,7 +670,9 @@ void RemoteClient::SendObjectData(
s32 sum = (s32)os.tellp() + 2 + (s32)bos.tellp(); s32 sum = (s32)os.tellp() + 2 + (s32)bos.tellp();
// break out if data too big // break out if data too big
if(sum > MAX_OBJECTDATA_SIZE) if(sum > MAX_OBJECTDATA_SIZE)
d = d_max+1; {
goto skip_subsequent;
}
} //try } //try
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -692,28 +694,7 @@ void RemoteClient::SendObjectData(
} }
} }
#if 0 skip_subsequent:
/*
Write objects
*/
// Write block count
writeU16(buf, blockcount);
os.write((char*)buf, 2);
for(core::map<v3s16, MapBlock*>::Iterator
i = blocks.getIterator();
i.atEnd() == false; i++)
{
v3s16 p = i.getNode()->getKey();
// Write blockpos
writeV3S16(buf, p);
os.write((char*)buf, 6);
// Write objects
MapBlock *block = i.getNode()->getValue();
block->serializeObjects(os, serialization_version);
}
#endif
// Write block count // Write block count
writeU16(buf, blockcount); writeU16(buf, blockcount);

@ -53,6 +53,8 @@ public:
*/ */
void addBlock(u16 peer_id, v3s16 pos, u8 flags) void addBlock(u16 peer_id, v3s16 pos, u8 flags)
{ {
DSTACK(__FUNCTION_NAME);
JMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
if(peer_id != 0) if(peer_id != 0)

@ -297,7 +297,13 @@ bool UDPSocket::WaitData(int timeout_ms)
dstream<<(int)m_handle<<": Select failed: "<<strerror(errno)<<std::endl; dstream<<(int)m_handle<<": Select failed: "<<strerror(errno)<<std::endl;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
dstream<<(int)m_handle<<": WSAGetLastError()="<<WSAGetLastError()<<std::endl; int e = WSAGetLastError();
dstream<<(int)m_handle<<": WSAGetLastError()="<<e<<std::endl;
if(e == 10004 /*=WSAEINTR*/)
{
dstream<<"WARNING: Ignoring WSAEINTR."<<std::endl;
return false;
}
#endif #endif
throw SocketException("Select failed"); throw SocketException("Select failed");
} }