better debug output in segfaults and stack overflows in windows
authorPerttu Ahola <celeron55@gmail.com>
Mon, 27 Dec 2010 12:34:17 +0000 (14:34 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 27 Dec 2010 12:34:17 +0000 (14:34 +0200)
minetest.vcproj
src/client.cpp
src/debug.cpp
src/debug.h
src/main.cpp
src/mapblock.cpp
src/materials.h
src/server.cpp
src/servermain.cpp

index 45d6027dd8592501871bd57adf2c3d702f052e19..c244b4370253b828aecd8579061993a85e57cf99 100644 (file)
                                WholeProgramOptimization="true"\r
                                AdditionalIncludeDirectories="&quot;C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include&quot;;&quot;..\jthread\jthread-1.2.1\src&quot;;&quot;..\irrlicht\irrlicht-1.7.1\include&quot;;&quot;..\zlib\zlib-1.2.5&quot;"\r
                                PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE,_CRT_SECURE_NO_DEPRECATE"\r
+                               ExceptionHandling="2"\r
                                BufferSecurityCheck="false"\r
                                EnableEnhancedInstructionSet="1"\r
                                FloatingPointModel="2"\r
index af2b375f48dbf52d5f81f72ce38e07c5c9d358bb..4792490f9fd67816782735396d1e27dba3951fcb 100644 (file)
@@ -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;
 }
index df8cbeb2268c7c593e0144d582e55ed88fdb93be..9fbdf7a396491d9c8d2304c44ad737ea41188268 100644 (file)
@@ -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
+
+
+
index 3f269176abcf889cf7fe06fff820382efde4b6d0..8faa65eb85b7898a9e5437ae9706fa869c47f062 100644 (file)
@@ -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 @@ private:
        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
 
index bd0ebd8cae79f0e78a16423483e6fd12e466d75c..f9022de648f5b608d952e6ec79a30adf8a22915e 100644 (file)
@@ -135,6 +135,13 @@ TODO: Make fetching sector's blocks more efficient when rendering
 \r
 TODO: Make the video backend selectable\r
 \r
+TODO: Copy the text of the last picked sign to inventory in creative\r
+      mode\r
+\r
+TODO: Get rid of GotSplitPacketException\r
+\r
+TODO: Check what goes wrong with caching map to disk (Kray)\r
+\r
 Block object server side:\r
       - A "near blocks" buffer, in which some nearby blocks are stored.\r
          - For all blocks in the buffer, objects are stepped(). This\r
@@ -146,17 +153,6 @@ Block object server side:
            - TODO: For incoming blocks, time difference is calculated and\r
              objects are stepped according to it.\r
 \r
-TODO: Copy the text of the last picked sign to inventory in creative\r
-      mode\r
-\r
-TODO: Get rid of GotSplitPacketException\r
-\r
-TODO: Check what goes wrong with caching map to disk (Kray)\r
-\r
-TODO: Remove LazyMeshUpdater. It is not used as supposed.\r
-\r
-TODO: TOSERVER_LEAVE\r
-\r
 TODO: Better handling of objects and mobs\r
       - Scripting?\r
       - There has to be some way to do it with less spaghetti code\r
@@ -171,6 +167,7 @@ TODO: Draw big amounts of torches better (that is, throw them in the
 \r
 TODO: Check if the usage of Client::isFetchingBlocks() in\r
       updateViewingRange() actually does something\r
+         NOTE: It isn't used anymore after the rewrite.\r
 \r
 TODO: Make an option to the server to disable building and digging near\r
       the starting position\r
@@ -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\r
       send them all the time. This affects signs and item objects.\r
 \r
-Doing now:\r
-======================================================================\r
-\r
 TODO: When server sees that client is removing an inexistent block or\r
       adding a block to an existent position, resend the MapBlock.\r
 \r
-TODO: Fix viewing range updater's oscillation when there is large non-\r
-      linearity in range-speed relation\r
+TODO: Map generator: add other materials underground (mud)\r
+\r
+Doing now:\r
+======================================================================\r
 \r
 ======================================================================\r
 \r
@@ -1095,6 +1091,8 @@ int main(int argc, char *argv[])
        \r
        initializeMaterialProperties();\r
 \r
+       BEGIN_DEBUG_EXCEPTION_HANDLER\r
+\r
        try\r
        {\r
        \r
@@ -1407,7 +1405,7 @@ int main(int argc, char *argv[])
        /*\r
                This changes the minimum allowed number of vertices in a VBO\r
        */\r
-       //driver->setMinHardwareBufferVertexCount(1);\r
+       //driver->setMinHardwareBufferVertexCount(50);\r
 \r
        scene::ISceneManager* smgr = device->getSceneManager();\r
        \r
@@ -2606,18 +2604,9 @@ int main(int argc, char *argv[])
                        menu->drop();\r
                }*/\r
        }\r
-#if CATCH_UNHANDLED_EXCEPTIONS\r
-       /*\r
-               This is what has to be done in every thread to get suitable debug info\r
-       */\r
-       catch(std::exception &e)\r
-       {\r
-               dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "\r
-                               <<e.what()<<std::endl;\r
-               assert(0);\r
-       }\r
-#endif\r
 \r
+       END_DEBUG_EXCEPTION_HANDLER\r
+       \r
        debugstreams_deinit();\r
        \r
        return 0;\r
index 20287732253d2a4f9fb17426187338ace1c78fc6..e828183969d7d4df7901faf7c54958977301ae41 100644 (file)
@@ -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 "
index ae2deac88d3dc13707af0b4d0304406ca30a1057..4221497536885028b6c55215d7d4bb7bde029525 100644 (file)
@@ -54,7 +54,6 @@ class MaterialProperties
 public:
        MaterialProperties()
        {
-               dstream<<__FUNCTION_NAME<<std::endl;
        }
 
        void setDiggingProperties(const std::string toolname,
index cbe2b932fe4641ecd07bbc25361ba6c028a5e1ba..05ef13d93172cdd6dac99d824e427085fbbdac5b 100644 (file)
@@ -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;
 }
index 594f7f4a236c8657bc7f71f89b363dd366d14da0..01919a7dfb5f25d70044b86d91ba9f805ddd4c45 100644 (file)
@@ -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();