mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
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"
|
||||
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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 "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
|
||||
|
||||
|
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: 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;
|
||||
|
@ -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,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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user