forked from Mirrorlandia_minetest/minetest
better debug output in segfaults and stack overflows in windows
This commit is contained in:
parent
847a4227b8
commit
fa64103aa8
@ -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"
|
||||||
|
@ -31,34 +31,22 @@ void * ClientUpdateThread::Thread()
|
|||||||
ThreadStarted();
|
ThreadStarted();
|
||||||
|
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
#if CATCH_UNHANDLED_EXCEPTIONS
|
BEGIN_DEBUG_EXCEPTION_HANDLER
|
||||||
try
|
|
||||||
|
while(getRun())
|
||||||
{
|
{
|
||||||
#endif
|
m_client->asyncStep();
|
||||||
while(getRun())
|
|
||||||
{
|
|
||||||
m_client->asyncStep();
|
|
||||||
|
|
||||||
//m_client->updateSomeExpiredMeshes();
|
//m_client->updateSomeExpiredMeshes();
|
||||||
|
|
||||||
bool was = m_client->AsyncProcessData();
|
bool was = m_client->AsyncProcessData();
|
||||||
|
|
||||||
if(was == false)
|
if(was == false)
|
||||||
sleep_ms(10);
|
sleep_ms(10);
|
||||||
}
|
|
||||||
#if CATCH_UNHANDLED_EXCEPTIONS
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
This is what has to be done in threads to get suitable debug info
|
END_DEBUG_EXCEPTION_HANDLER
|
||||||
*/
|
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
63
src/debug.h
63
src/debug.h
@ -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
|
||||||
|
|
||||||
|
45
src/main.cpp
45
src/main.cpp
@ -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,18 +2604,9 @@ int main(int argc, char *argv[])
|
|||||||
menu->drop();
|
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();
|
debugstreams_deinit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -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,11 +67,9 @@ void * EmergeThread::Thread()
|
|||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
bool debug=false;
|
bool debug=false;
|
||||||
#if CATCH_UNHANDLED_EXCEPTIONS
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
BEGIN_DEBUG_EXCEPTION_HANDLER
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get block info from queue, emerge them and send them
|
Get block info from queue, emerge them and send them
|
||||||
to clients.
|
to clients.
|
||||||
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user