diff --git a/Makefile b/Makefile
index 979631fc0f79b1405a86bbf54958e92eda8b5652..2b4e8dda3e20441aeb3f3543e4370bf6815b4c87 100644
--- a/Makefile
+++ b/Makefile
@@ -21,8 +21,8 @@ CXXFLAGS = -O2 -ffast-math -Wall -g -pipe
 #CXXFLAGS = -O3 -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 -fwhole-program
+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
 
 #Default target
 
@@ -53,9 +53,9 @@ all_linux all_win32: $(DESTPATH)
 fast_linux: $(FASTDESTPATH)
 
 $(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")
-	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)
 	$(CXX) -o $@ $(OBJECTS) $(LDFLAGS)
diff --git a/minetest.vcproj b/minetest.vcproj
index 0401e2a04c55ce9ff6f3c1204cd167590f0cd302..6ebfaee7f7b82b95f1e1ea3ef4f8095cb850e481 100644
--- a/minetest.vcproj
+++ b/minetest.vcproj
@@ -41,6 +41,7 @@
 				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""
 				PreprocessorDefinitions="WIN32"
+				BufferSecurityCheck="true"
 				EnableEnhancedInstructionSet="1"
 				FloatingPointModel="2"
 				DebugInformationFormat="1"
@@ -117,10 +118,11 @@
 				OmitFramePointers="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""
-				PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE"
+				PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE,_CRT_SECURE_NO_DEPRECATE"
 				BufferSecurityCheck="false"
 				EnableEnhancedInstructionSet="1"
 				FloatingPointModel="2"
+				DebugInformationFormat="0"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -135,6 +137,7 @@
 				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;"
 				IgnoreDefaultLibraryNames="libcmtd.lib"
+				GenerateDebugInformation="false"
 				LinkTimeCodeGeneration="1"
 			/>
 			<Tool
diff --git a/src/constants.h b/src/constants.h
index 8cc4ee473aa6338d94648dd67ea80edfea85369e..d8435e36dee8f881d0876d6089b6f2df496fb3b3 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -56,8 +56,9 @@
 // The distance of how far objects will be sent to client
 //#define ACTIVE_OBJECT_D_BLOCKS 2
 
-// Wether to catch all std::exceptions
-#define CATCH_UNHANDLED_EXCEPTIONS 0
+// Wether to catch all std::exceptions.
+// Assert will be called on such an event.
+#define CATCH_UNHANDLED_EXCEPTIONS 1
 
 /*
 	Collecting active blocks is stopped after object data
diff --git a/src/debug.cpp b/src/debug.cpp
index 2489413862615473166ad2bbe09ad9e8119364b2..a2b28cd72d802d64c61168a2cfbe5c183585de19 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -84,7 +84,7 @@ DebugStack::DebugStack(threadid_t id)
 
 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);
 
 	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)
 			continue;
 
-		if(everything == true && i == stack_i)
-			fprintf(file, "END OF STACK.\n"
-					"! Continuing beyond stack end:\n");
-
-		fprintf(file, "#%d  %s\n", i, stack[i]);
+		if(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)
diff --git a/src/main.cpp b/src/main.cpp
index 0452aca317db5e1eae3b880c8fe126c091fd013f..f7b2b2c6baa84624d344cee4df98679e93d4f8bf 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -474,6 +474,18 @@ class MyEventReceiver : public IEventReceiver
 						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;
 	}
-#if CATCH_EXCEPTIONS
+#if CATCH_UNHANDLED_EXCEPTIONS
 	/*
 		This is what has to be done in every thread to get suitable debug info
 	*/
diff --git a/src/map.cpp b/src/map.cpp
index a51113c2d52e8351ad1f1369486579481b8a944f..33501a32f23f23c99a563a462c477a2b8a947b79 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1522,7 +1522,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
 	*/
 	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 x = rand()%(MAP_BLOCKSIZE-s*2-1)+s;
@@ -1662,8 +1662,16 @@ MapBlock * ServerMap::emergeBlock(
 	for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
 	{
 		//dstream<<"emergeBlock: x0="<<x0<<", z0="<<z0<<std::endl;
+
 		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;
 		//avg_ground_y += surface_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)
 {
 	DSTACK(__FUNCTION_NAME);
+
+	try{
+
 	// Block file is map/sectors/xxxxxxxx/xxxx
 	std::string fullpath = m_savedir+"/sectors/"+sectordir+"/"+blockfile;
 	std::ifstream is(fullpath.c_str(), std::ios_base::binary);
@@ -2483,7 +2494,8 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
 		block = sector->createBlankBlockNoInsert(p3d.Y);
 		created_new = true;
 	}
-
+	
+	// deserialize block data
 	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.
 	block->resetChangedFlag();
+
+	}
+	catch(SerializationError &e)
+	{
+		dstream<<"WARNING: Invalid block data on disk "
+				"(SerializationError). Ignoring."
+				<<std::endl;
+	}
 }
 
 // Gets from master heightmap
diff --git a/src/map.h b/src/map.h
index 2f0942182068a7d2cdf69b9e2dd682d0065991ae..5b04ae9d17f0954aae24dffccd818b31831166b1 100644
--- a/src/map.h
+++ b/src/map.h
@@ -106,6 +106,7 @@ class CacheLock
 
 	void cacheCreated()
 	{
+		dstream<<"cacheCreated() begin"<<std::endl;
 		JMutexAutoLock waitcachelock(m_waitcache_mutex);
 		JMutexAutoLock countlock(m_count_mutex);
 
@@ -114,10 +115,13 @@ class CacheLock
 			m_cache_mutex.Lock();
 			
 		m_count++;
+
+		dstream<<"cacheCreated() end"<<std::endl;
 	}
 
 	void cacheRemoved()
 	{
+		dstream<<"cacheRemoved() begin"<<std::endl;
 		JMutexAutoLock countlock(m_count_mutex);
 
 		assert(m_count > 0);
@@ -127,6 +131,8 @@ class CacheLock
 		// If this is the last one, release the cache lock
 		if(m_count == 0)
 			m_cache_mutex.Unlock();
+
+		dstream<<"cacheRemoved() end"<<std::endl;
 	}
 
 	/*
@@ -137,8 +143,11 @@ class CacheLock
 	*/
 	JMutexAutoLock * waitCaches()
 	{
+		dstream<<"waitCaches() begin"<<std::endl;
 		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:
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 5ca8749463ef8a14f10717653854ffe99d8d4416..c4c4ad7959f4e0fbddc0d3388e8d4909461b9dbe 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -356,9 +356,10 @@ class MeshCollector
 			
 			// This is a "Standard MeshBuffer",
 			// it's a typedeffed CMeshBuffer<video::S3DVertex>
-			scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+			scene::SMeshBuffer *buf = new scene::SMeshBuffer();
 			// Set material
-			((scene::SMeshBuffer*)buf)->Material = p.material;
+			buf->Material = p.material;
+			//((scene::SMeshBuffer*)buf)->Material = p.material;
 			// Use VBO
 			//buf->setHardwareMappingHint(scene::EHM_STATIC);
 			// Add to mesh
diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp
index 985a01dc160ad4d813b60b21bfffedfc96b86771..df070265c7600441bf76b5e921ab086c3d10f708 100644
--- a/src/mapblockobject.cpp
+++ b/src/mapblockobject.cpp
@@ -33,8 +33,16 @@ void MapBlockObject::setBlockChanged()
 */
 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);
 	
 	if(m_block->isValidPosition(oldpos_i) == false)
@@ -50,6 +58,16 @@ void MovingObject::move(float dtime, v3f acceleration)
 		m_pos += m_speed * dtime;
 		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 oldpos = position;
@@ -471,40 +489,53 @@ MapBlockObject * MapBlockObjectList::get(s16 id)
 
 void MapBlockObjectList::step(float dtime, bool server)
 {
+	DSTACK(__FUNCTION_NAME);
+	
 	JMutexAutoLock lock(m_mutex);
-
+	
 	core::map<s16, bool> ids_to_delete;
 
-	for(core::map<s16, MapBlockObject*>::Iterator
-			i = m_objects.getIterator();
-			i.atEnd() == false; i++)
 	{
-		MapBlockObject *obj = i.getNode()->getValue();
-		
-		if(server)
-		{
-			bool to_delete = obj->serverStep(dtime);
+		DSTACK("%s: stepping objects", __FUNCTION_NAME);
 
-			if(to_delete)
-				ids_to_delete.insert(obj->m_id, true);
-		}
-		else
+		for(core::map<s16, MapBlockObject*>::Iterator
+				i = m_objects.getIterator();
+				i.atEnd() == false; i++)
 		{
-			obj->clientStep(dtime);
+			MapBlockObject *obj = i.getNode()->getValue();
+			
+			DSTACK("%s: stepping object type %i", __FUNCTION_NAME,
+					obj->getTypeId());
+
+			if(server)
+			{
+				bool to_delete = obj->serverStep(dtime);
+
+				if(to_delete)
+					ids_to_delete.insert(obj->m_id, true);
+			}
+			else
+			{
+				obj->clientStep(dtime);
+			}
 		}
 	}
 
-	// Delete objects in delete queue
-	for(core::map<s16, bool>::Iterator
-			i = ids_to_delete.getIterator();
-			i.atEnd() == false; i++)
 	{
-		s16 id = i.getNode()->getKey();
+		DSTACK("%s: deleting objects", __FUNCTION_NAME);
 
-		MapBlockObject *obj = m_objects[id];
-		obj->removeFromScene();
-		delete obj;
-		m_objects.remove(id);
+		// Delete objects in delete queue
+		for(core::map<s16, bool>::Iterator
+				i = ids_to_delete.getIterator();
+				i.atEnd() == false; i++)
+		{
+			s16 id = i.getNode()->getKey();
+
+			MapBlockObject *obj = m_objects[id];
+			obj->removeFromScene();
+			delete obj;
+			m_objects.remove(id);
+		}
 	}
 	
 	/*
@@ -513,36 +544,42 @@ void MapBlockObjectList::step(float dtime, bool server)
 
 	if(server == false)
 		return;
-
-	for(core::map<s16, MapBlockObject*>::Iterator
-			i = m_objects.getIterator();
-			i.atEnd() == false; i++)
+	
 	{
-		MapBlockObject *obj = i.getNode()->getValue();
-
-		v3s16 pos_i = floatToInt(obj->m_pos);
+		DSTACK("%s: object wrap loop", __FUNCTION_NAME);
 
-		if(m_block->isValidPosition(pos_i))
+		for(core::map<s16, MapBlockObject*>::Iterator
+				i = m_objects.getIterator();
+				i.atEnd() == false; i++)
 		{
-			// No wrap
-			continue;
-		}
+			MapBlockObject *obj = i.getNode()->getValue();
 
-		bool impossible = wrapObject(obj);
+			v3s16 pos_i = floatToInt(obj->m_pos);
 
-		if(impossible)
-		{
-			// No wrap
-			continue;
-		}
+			if(m_block->isValidPosition(pos_i))
+			{
+				// No wrap
+				continue;
+			}
 
-		// Restart find
-		i = m_objects.getIterator();
+			bool impossible = wrapObject(obj);
+
+			if(impossible)
+			{
+				// No wrap
+				continue;
+			}
+
+			// Restart find
+			i = m_objects.getIterator();
+		}
 	}
 }
 
 bool MapBlockObjectList::wrapObject(MapBlockObject *object)
 {
+	DSTACK(__FUNCTION_NAME);
+	
 	// No lock here; this is called so that the lock is already locked.
 	//JMutexAutoLock lock(m_mutex);
 
diff --git a/src/mapblockobject.h b/src/mapblockobject.h
index 15409bbd76696278544b44549dc25c52ee53782f..ea0293a6f6359cfc6a0d3082f4efe2e8f85fc7cb 100644
--- a/src/mapblockobject.h
+++ b/src/mapblockobject.h
@@ -11,6 +11,7 @@
 #include "serialization.h"
 #include "mapnode.h"
 #include "constants.h"
+#include "debug.h"
 
 enum
 {
diff --git a/src/server.cpp b/src/server.cpp
index 16f6611cafbcd0b1a10d0cc8bbb03bb06acac05b..a4035284718defead7336bea5cd9fd84e0c9455c 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -670,7 +670,9 @@ void RemoteClient::SendObjectData(
 			s32 sum = (s32)os.tellp() + 2 + (s32)bos.tellp();
 			// break out if data too big
 			if(sum > MAX_OBJECTDATA_SIZE)
-				d = d_max+1;
+			{
+				goto skip_subsequent;
+			}
 			
 			} //try
 			catch(InvalidPositionException &e)
@@ -692,28 +694,7 @@ void RemoteClient::SendObjectData(
 		}
 	}
 
-#if 0
-	/*
-		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
+skip_subsequent:
 
 	// Write block count
 	writeU16(buf, blockcount);
diff --git a/src/server.h b/src/server.h
index 79cdf052d6fd04052242e8cce58794c3f6249d1a..9c5850bff69bd1c19281d7743ef8aac810895fb8 100644
--- a/src/server.h
+++ b/src/server.h
@@ -53,6 +53,8 @@ class BlockEmergeQueue
 	*/
 	void addBlock(u16 peer_id, v3s16 pos, u8 flags)
 	{
+		DSTACK(__FUNCTION_NAME);
+	
 		JMutexAutoLock lock(m_mutex);
 
 		if(peer_id != 0)
diff --git a/src/socket.cpp b/src/socket.cpp
index 88ba78c6ad0c601dde7ca195e1a9494161e0e9b2..dddc8f36a30339abf7f5ca15bf669342f183661e 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -297,7 +297,13 @@ bool UDPSocket::WaitData(int timeout_ms)
 		dstream<<(int)m_handle<<": Select failed: "<<strerror(errno)<<std::endl;
 #endif
 #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
 		throw SocketException("Select failed");
 	}