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

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

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

@ -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,17 +2604,8 @@ 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();

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

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

@ -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,10 +67,8 @@ 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
@ -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;
}

@ -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();