diff --git a/minetest.vcproj b/minetest.vcproj
index 45d6027dd8592501871bd57adf2c3d702f052e19..c244b4370253b828aecd8579061993a85e57cf99 100644
--- a/minetest.vcproj
+++ b/minetest.vcproj
@@ -119,6 +119,7 @@
 				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";"..\zlib\zlib-1.2.5""
 				PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE,_CRT_SECURE_NO_DEPRECATE"
+				ExceptionHandling="2"
 				BufferSecurityCheck="false"
 				EnableEnhancedInstructionSet="1"
 				FloatingPointModel="2"
diff --git a/src/client.cpp b/src/client.cpp
index af2b375f48dbf52d5f81f72ce38e07c5c9d358bb..4792490f9fd67816782735396d1e27dba3951fcb 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -31,34 +31,22 @@ void * ClientUpdateThread::Thread()
 	ThreadStarted();
 
 	DSTACK(__FUNCTION_NAME);
-
-#if CATCH_UNHANDLED_EXCEPTIONS
-	try
+	
+	BEGIN_DEBUG_EXCEPTION_HANDLER
+	
+	while(getRun())
 	{
-#endif
-		while(getRun())
-		{
-			m_client->asyncStep();
+		m_client->asyncStep();
 
-			//m_client->updateSomeExpiredMeshes();
+		//m_client->updateSomeExpiredMeshes();
 
-			bool was = m_client->AsyncProcessData();
+		bool was = m_client->AsyncProcessData();
 
-			if(was == false)
-				sleep_ms(10);
-		}
-#if CATCH_UNHANDLED_EXCEPTIONS
+		if(was == false)
+			sleep_ms(10);
 	}
-	/*
-		This is what has to be done in threads to get suitable debug info
-	*/
-	catch(std::exception &e)
-	{
-		dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
-				<<e.what()<<std::endl;
-		assert(0);
-	}
-#endif
+
+	END_DEBUG_EXCEPTION_HANDLER
 
 	return NULL;
 }
diff --git a/src/debug.cpp b/src/debug.cpp
index df8cbeb2268c7c593e0144d582e55ed88fdb93be..9fbdf7a396491d9c8d2304c44ad737ea41188268 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -194,3 +194,33 @@ DebugStacker::~DebugStacker()
 	}
 }
 
+
+#ifdef _WIN32
+void se_trans_func(unsigned int u, EXCEPTION_POINTERS* pExp)
+{
+	dstream<<"In trans_func.\n";
+	if(u == EXCEPTION_ACCESS_VIOLATION)
+	{
+		PEXCEPTION_RECORD r = pExp->ExceptionRecord;
+		dstream<<"Access violation at "<<r->ExceptionAddress
+				<<" write?="<<r->ExceptionInformation[0]
+				<<" address="<<r->ExceptionInformation[1]
+				<<std::endl;
+		throw FatalSystemException
+		("Access violation");
+	}
+	if(u == EXCEPTION_STACK_OVERFLOW)
+	{
+		throw FatalSystemException
+		("Stack overflow");
+	}
+	if(u == EXCEPTION_ILLEGAL_INSTRUCTION)
+	{
+		throw FatalSystemException
+		("Illegal instruction");
+	}
+}
+#endif
+
+
+
diff --git a/src/debug.h b/src/debug.h
index 3f269176abcf889cf7fe06fff820382efde4b6d0..8faa65eb85b7898a9e5437ae9706fa869c47f062 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -27,6 +27,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "common_irrlicht.h"
 #include "threads.h"
 #include "gettime.h"
+#include "constants.h"
+#include "exceptions.h"
+
+#ifdef _WIN32
+	#define WIN32_LEAN_AND_MEAN
+	#include <windows.h>
+	#include <eh.h>
+#else
+#endif
 
 /*
 	Debug output
@@ -215,6 +224,60 @@ class PacketCounter
 	core::map<u16, u16> m_packets;
 };
 
+/*
+	These should be put into every thread
+*/
+
+#if CATCH_UNHANDLED_EXCEPTIONS == 1
+	#define BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER try{
+	#define END_PORTABLE_DEBUG_EXCEPTION_HANDLER\
+		}catch(std::exception &e){\
+			dstream<<std::endl<<DTIME\
+					<<"ERROR: An unhandled exception occurred: "\
+					<<e.what()<<std::endl;\
+			assert(0);\
+		}
+	#ifdef _WIN32 // Windows
+
+/*class SE_Exception : public std::exception
+{
+private:
+    unsigned int nSE;
+public:
+    SE_Exception() {}
+    SE_Exception( unsigned int n ) : nSE( n ) {}
+    ~SE_Exception() {}
+    unsigned int getSeNumber() { return nSE; }
+};*/
+
+void se_trans_func(unsigned int, EXCEPTION_POINTERS*);
+
+class FatalSystemException : public BaseException
+{
+public:
+	FatalSystemException(const char *s):
+		BaseException(s)
+	{}
+};
+
+		#define BEGIN_DEBUG_EXCEPTION_HANDLER \
+			BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER\
+			_set_se_translator(se_trans_func);
+
+		#define END_DEBUG_EXCEPTION_HANDLER \
+			END_PORTABLE_DEBUG_EXCEPTION_HANDLER
+
+	#else // Posix
+		#define BEGIN_DEBUG_EXCEPTION_HANDLER\
+			BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER
+		#define END_DEBUG_EXCEPTION_HANDLER\
+			END_PORTABLE_DEBUG_EXCEPTION_HANDLER
+	#endif
+#else
+	// Dummy ones
+	#define BEGIN_DEBUG_EXCEPTION_HANDLER
+	#define END_DEBUG_EXCEPTION_HANDLER
+#endif
 
 #endif // DEBUG_HEADER
 
diff --git a/src/main.cpp b/src/main.cpp
index bd0ebd8cae79f0e78a16423483e6fd12e466d75c..f9022de648f5b608d952e6ec79a30adf8a22915e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -135,6 +135,13 @@ TODO: Make fetching sector's blocks more efficient when rendering
 
 TODO: Make the video backend selectable
 
+TODO: Copy the text of the last picked sign to inventory in creative
+      mode
+
+TODO: Get rid of GotSplitPacketException
+
+TODO: Check what goes wrong with caching map to disk (Kray)
+
 Block object server side:
       - A "near blocks" buffer, in which some nearby blocks are stored.
 	  - For all blocks in the buffer, objects are stepped(). This
@@ -146,17 +153,6 @@ Block object server side:
 	    - TODO: For incoming blocks, time difference is calculated and
 	      objects are stepped according to it.
 
-TODO: Copy the text of the last picked sign to inventory in creative
-      mode
-
-TODO: Get rid of GotSplitPacketException
-
-TODO: Check what goes wrong with caching map to disk (Kray)
-
-TODO: Remove LazyMeshUpdater. It is not used as supposed.
-
-TODO: TOSERVER_LEAVE
-
 TODO: Better handling of objects and mobs
       - Scripting?
       - There has to be some way to do it with less spaghetti code
@@ -171,6 +167,7 @@ TODO: Draw big amounts of torches better (that is, throw them in the
 
 TODO: Check if the usage of Client::isFetchingBlocks() in
       updateViewingRange() actually does something
+	  NOTE: It isn't used anymore after the rewrite.
 
 TODO: Make an option to the server to disable building and digging near
       the starting position
@@ -181,14 +178,13 @@ SUGG: Signs could be done in the same way as torches. For this, blocks
 TODO: There has to be some better way to handle static objects than to
       send them all the time. This affects signs and item objects.
 
-Doing now:
-======================================================================
-
 TODO: When server sees that client is removing an inexistent block or
       adding a block to an existent position, resend the MapBlock.
 
-TODO: Fix viewing range updater's oscillation when there is large non-
-      linearity in range-speed relation
+TODO: Map generator: add other materials underground (mud)
+
+Doing now:
+======================================================================
 
 ======================================================================
 
@@ -1095,6 +1091,8 @@ int main(int argc, char *argv[])
 	
 	initializeMaterialProperties();
 
+	BEGIN_DEBUG_EXCEPTION_HANDLER
+
 	try
 	{
 	
@@ -1407,7 +1405,7 @@ int main(int argc, char *argv[])
 	/*
 		This changes the minimum allowed number of vertices in a VBO
 	*/
-	//driver->setMinHardwareBufferVertexCount(1);
+	//driver->setMinHardwareBufferVertexCount(50);
 
 	scene::ISceneManager* smgr = device->getSceneManager();
 	
@@ -2606,18 +2604,9 @@ int main(int argc, char *argv[])
 			menu->drop();
 		}*/
 	}
-#if CATCH_UNHANDLED_EXCEPTIONS
-	/*
-		This is what has to be done in every thread to get suitable debug info
-	*/
-	catch(std::exception &e)
-	{
-		dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
-				<<e.what()<<std::endl;
-		assert(0);
-	}
-#endif
 
+	END_DEBUG_EXCEPTION_HANDLER
+	
 	debugstreams_deinit();
 	
 	return 0;
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 20287732253d2a4f9fb17426187338ace1c78fc6..e828183969d7d4df7901faf7c54958977301ae41 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -275,6 +275,10 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
 */
 TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
 {
+	// DEBUG
+	u16 *ptr = NULL;
+	*ptr = 7357;
+
 	TileSpec spec;
 
 	/*//DEBUG
@@ -688,6 +692,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
 		collector.fillMesh(mesh_new);
 
 		// Use VBO for mesh (this just would set this for ever buffer)
+		// This will lead to infinite memory usage because or irrlicht.
 		//mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
 		
 		/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
diff --git a/src/materials.h b/src/materials.h
index ae2deac88d3dc13707af0b4d0304406ca30a1057..4221497536885028b6c55215d7d4bb7bde029525 100644
--- a/src/materials.h
+++ b/src/materials.h
@@ -54,7 +54,6 @@ class MaterialProperties
 public:
 	MaterialProperties()
 	{
-		dstream<<__FUNCTION_NAME<<std::endl;
 	}
 
 	void setDiggingProperties(const std::string toolname,
diff --git a/src/server.cpp b/src/server.cpp
index cbe2b932fe4641ecd07bbc25361ba6c028a5e1ba..05ef13d93172cdd6dac99d824e427085fbbdac5b 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -40,6 +40,8 @@ void * ServerThread::Thread()
 
 	DSTACK(__FUNCTION_NAME);
 
+	BEGIN_DEBUG_EXCEPTION_HANDLER
+
 	while(getRun())
 	{
 		try{
@@ -51,19 +53,9 @@ void * ServerThread::Thread()
 		catch(con::NoIncomingDataException &e)
 		{
 		}
-#if CATCH_UNHANDLED_EXCEPTIONS
-		/*
-			This is what has to be done in threads to get suitable debug info
-		*/
-		catch(std::exception &e)
-		{
-			dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
-					<<e.what()<<std::endl;
-			assert(0);
-		}
-#endif
 	}
 	
+	END_DEBUG_EXCEPTION_HANDLER
 
 	return NULL;
 }
@@ -75,11 +67,9 @@ void * EmergeThread::Thread()
 	DSTACK(__FUNCTION_NAME);
 
 	bool debug=false;
-#if CATCH_UNHANDLED_EXCEPTIONS
-	try
-	{
-#endif
 	
+	BEGIN_DEBUG_EXCEPTION_HANDLER
+
 	/*
 		Get block info from queue, emerge them and send them
 		to clients.
@@ -267,18 +257,8 @@ void * EmergeThread::Thread()
 		}
 		
 	}
-#if CATCH_UNHANDLED_EXCEPTIONS
-	}//try
-	/*
-		This is what has to be done in threads to get suitable debug info
-	*/
-	catch(std::exception &e)
-	{
-		dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
-				<<e.what()<<std::endl;
-		assert(0);
-	}
-#endif
+
+	END_DEBUG_EXCEPTION_HANDLER
 
 	return NULL;
 }
diff --git a/src/servermain.cpp b/src/servermain.cpp
index 594f7f4a236c8657bc7f71f89b363dd366d14da0..01919a7dfb5f25d70044b86d91ba9f805ddd4c45 100644
--- a/src/servermain.cpp
+++ b/src/servermain.cpp
@@ -125,6 +125,8 @@ int main(int argc, char *argv[])
 
 	initializeMaterialProperties();
 
+	BEGIN_DEBUG_EXCEPTION_HANDLER
+
 	try
 	{
 	
@@ -345,17 +347,8 @@ int main(int argc, char *argv[])
 	{
 		dstream<<DTIME<<"Connection timed out."<<std::endl;
 	}
-#if CATCH_UNHANDLED_EXCEPTIONS
-	/*
-		This is what has to be done in every thread to get suitable debug info
-	*/
-	catch(std::exception &e)
-	{
-		dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
-				<<e.what()<<std::endl;
-		assert(0);
-	}
-#endif
+
+	END_DEBUG_EXCEPTION_HANDLER
 
 	debugstreams_deinit();