better debug output in segfaults and stack overflows in windows

This commit is contained in:
Perttu Ahola 2010-12-27 14:34:17 +02:00
parent 847a4227b8
commit fa64103aa8
9 changed files with 138 additions and 90 deletions

@ -119,6 +119,7 @@
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";"..\zlib\zlib-1.2.5"" 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" PreprocessorDefinitions="WIN32;_HAS_ITERATOR_DEBUGGING=0,UNITTEST_DISABLE,_CRT_SECURE_NO_DEPRECATE"
ExceptionHandling="2"
BufferSecurityCheck="false" BufferSecurityCheck="false"
EnableEnhancedInstructionSet="1" EnableEnhancedInstructionSet="1"
FloatingPointModel="2" FloatingPointModel="2"

@ -32,10 +32,8 @@ void * ClientUpdateThread::Thread()
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
#if CATCH_UNHANDLED_EXCEPTIONS BEGIN_DEBUG_EXCEPTION_HANDLER
try
{
#endif
while(getRun()) while(getRun())
{ {
m_client->asyncStep(); m_client->asyncStep();
@ -47,18 +45,8 @@ void * ClientUpdateThread::Thread()
if(was == false) if(was == false)
sleep_ms(10); sleep_ms(10);
} }
#if CATCH_UNHANDLED_EXCEPTIONS
} END_DEBUG_EXCEPTION_HANDLER
/*
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
return NULL; return NULL;
} }

@ -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

@ -27,6 +27,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "threads.h" #include "threads.h"
#include "gettime.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 Debug output
@ -215,6 +224,60 @@ private:
core::map<u16, u16> m_packets; 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 #endif // DEBUG_HEADER

@ -135,6 +135,13 @@ TODO: Make fetching sector's blocks more efficient when rendering
TODO: Make the video backend selectable 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: Block object server side:
- A "near blocks" buffer, in which some nearby blocks are stored. - A "near blocks" buffer, in which some nearby blocks are stored.
- For all blocks in the buffer, objects are stepped(). This - 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 - TODO: For incoming blocks, time difference is calculated and
objects are stepped according to it. 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 TODO: Better handling of objects and mobs
- Scripting? - Scripting?
- There has to be some way to do it with less spaghetti code - 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 TODO: Check if the usage of Client::isFetchingBlocks() in
updateViewingRange() actually does something 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 TODO: Make an option to the server to disable building and digging near
the starting position 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 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. 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 TODO: When server sees that client is removing an inexistent block or
adding a block to an existent position, resend the MapBlock. adding a block to an existent position, resend the MapBlock.
TODO: Fix viewing range updater's oscillation when there is large non- TODO: Map generator: add other materials underground (mud)
linearity in range-speed relation
Doing now:
======================================================================
====================================================================== ======================================================================
@ -1095,6 +1091,8 @@ int main(int argc, char *argv[])
initializeMaterialProperties(); initializeMaterialProperties();
BEGIN_DEBUG_EXCEPTION_HANDLER
try try
{ {
@ -1407,7 +1405,7 @@ int main(int argc, char *argv[])
/* /*
This changes the minimum allowed number of vertices in a VBO This changes the minimum allowed number of vertices in a VBO
*/ */
//driver->setMinHardwareBufferVertexCount(1); //driver->setMinHardwareBufferVertexCount(50);
scene::ISceneManager* smgr = device->getSceneManager(); scene::ISceneManager* smgr = device->getSceneManager();
@ -2606,17 +2604,8 @@ int main(int argc, char *argv[])
menu->drop(); menu->drop();
}*/ }*/
} }
#if CATCH_UNHANDLED_EXCEPTIONS
/* END_DEBUG_EXCEPTION_HANDLER
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
debugstreams_deinit(); debugstreams_deinit();

@ -275,6 +275,10 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
*/ */
TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir) TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
{ {
// DEBUG
u16 *ptr = NULL;
*ptr = 7357;
TileSpec spec; TileSpec spec;
/*//DEBUG /*//DEBUG
@ -688,6 +692,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
collector.fillMesh(mesh_new); collector.fillMesh(mesh_new);
// Use VBO for mesh (this just would set this for ever buffer) // 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); //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces " /*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "

@ -54,7 +54,6 @@ class MaterialProperties
public: public:
MaterialProperties() MaterialProperties()
{ {
dstream<<__FUNCTION_NAME<<std::endl;
} }
void setDiggingProperties(const std::string toolname, void setDiggingProperties(const std::string toolname,

@ -40,6 +40,8 @@ void * ServerThread::Thread()
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
BEGIN_DEBUG_EXCEPTION_HANDLER
while(getRun()) while(getRun())
{ {
try{ try{
@ -51,19 +53,9 @@ void * ServerThread::Thread()
catch(con::NoIncomingDataException &e) 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; return NULL;
} }
@ -75,10 +67,8 @@ void * EmergeThread::Thread()
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
bool debug=false; bool debug=false;
#if CATCH_UNHANDLED_EXCEPTIONS
try BEGIN_DEBUG_EXCEPTION_HANDLER
{
#endif
/* /*
Get block info from queue, emerge them and send them Get block info from queue, emerge them and send them
@ -267,18 +257,8 @@ void * EmergeThread::Thread()
} }
} }
#if CATCH_UNHANDLED_EXCEPTIONS
}//try END_DEBUG_EXCEPTION_HANDLER
/*
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
return NULL; return NULL;
} }

@ -125,6 +125,8 @@ int main(int argc, char *argv[])
initializeMaterialProperties(); initializeMaterialProperties();
BEGIN_DEBUG_EXCEPTION_HANDLER
try try
{ {
@ -345,17 +347,8 @@ int main(int argc, char *argv[])
{ {
dstream<<DTIME<<"Connection timed out."<<std::endl; dstream<<DTIME<<"Connection timed out."<<std::endl;
} }
#if CATCH_UNHANDLED_EXCEPTIONS
/* END_DEBUG_EXCEPTION_HANDLER
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
debugstreams_deinit(); debugstreams_deinit();