diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 130b0cef..5c207131 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -148,7 +148,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) type = getint(p); #ifdef _DEBUG - if(type!=SV_POS && type!=SV_CLIENTPING && type!=SV_PING && type!=SV_PONG) + if(type!=SV_POS && type!=SV_CLIENTPING && type!=SV_PING && type!=SV_PONG && type!=SV_CLIENT) { DEBUGVAR(d); ASSERT(type>=0 && type + #include #define _WINDOWS #define ZLIB_DLL #endif diff --git a/source/src/server.cpp b/source/src/server.cpp index 357c040b..d72fc5f2 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2465,7 +2465,7 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1 type = checktype(getint(p), cl); #ifdef _DEBUG - if(type!=SV_POS && type!=SV_CLIENTPING && type!=SV_PING) + if(type!=SV_POS && type!=SV_CLIENTPING && type!=SV_PING && type!=SV_CLIENT) { DEBUGVAR(cl->name); ASSERT(type>=0 && typewriteline(log::error, out); else puts(out); exit(EXIT_FAILURE); @@ -3377,6 +3377,15 @@ void fatal(const char *s, ...) int main(int argc, char **argv) { + #ifdef WIN32 + //atexit((void (__cdecl *)(void))_CrtDumpMemoryLeaks); + #ifndef _DEBUG + #ifndef __GNUC__ + __try { + #endif + #endif + #endif + int uprate = 0, maxcl = DEFAULTCLIENTS, scthreshold = -5, port = 0, permdemo = -1; const char *sdesc = "", *sdesc_pre = "", *sdesc_suf = "", *ip = "", *master = NULL, *passwd = "", *maprot = "", *admpwd = NULL, *pwdfile = NULL, *blfile = NULL, *srvmsg = NULL, *service = NULL; @@ -3427,6 +3436,10 @@ int main(int argc, char **argv) if(enet_initialize()<0) fatal("Unable to initialise network module"); initserver(true, uprate, sdesc, sdesc_pre, sdesc_suf, ip, port, master, passwd, maxcl, maprot, admpwd, pwdfile, blfile, srvmsg, scthreshold, permdemo); return EXIT_SUCCESS; + + #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__) + } __except(stackdumper(0, GetExceptionInformation()), EXCEPTION_CONTINUE_SEARCH) { return 0; } + #endif } #endif diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 82fd246c..4e2fd492 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -302,6 +302,35 @@ bool delfile(const char *path) return !remove(path); } +///////////////////////// debugging /////////////////////// + +#if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__) +void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) +{ + if(!ep) fatal("unknown type"); + EXCEPTION_RECORD *er = ep->ExceptionRecord; + CONTEXT *context = ep->ContextRecord; + string out, t; + s_sprintf(out)("Win32 Exception: 0x%x [0x%x]\n\n", er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1); + STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0}; + SymInitialize(GetCurrentProcess(), NULL, TRUE); + + while(::StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL)) + { + struct { IMAGEHLP_SYMBOL sym; string n; } si = { { sizeof( IMAGEHLP_SYMBOL ), 0, 0, 0, sizeof(string) } }; + IMAGEHLP_LINE li = { sizeof( IMAGEHLP_LINE ) }; + DWORD off; + if(SymGetSymFromAddr(GetCurrentProcess(), (DWORD)sf.AddrPC.Offset, &off, &si.sym) && SymGetLineFromAddr(GetCurrentProcess(), (DWORD)sf.AddrPC.Offset, &off, &li)) + { + char *del = strrchr(li.FileName, '\\'); + s_sprintf(t)("%s - %s [%d]\n", si.sym.Name, del ? del + 1 : li.FileName, li.LineNumber); + s_strcat(out, t); + } + } + fatal(out); +} +#endif + ///////////////////////// misc tools /////////////////////// bool cmpb(void *b, int n, enet_uint32 c) diff --git a/source/src/tools.h b/source/src/tools.h index c6d26a4c..0c97884c 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -525,6 +525,7 @@ extern char *loadfile(const char *fn, int *size, const char *mode = NULL); extern bool listdir(const char *dir, const char *ext, vector &files); extern int listfiles(const char *dir, const char *ext, vector &files); extern bool delfile(const char *path); +extern void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep); extern bool cmpb(void *b, int n, enet_uint32 c); extern bool cmpf(char *fn, enet_uint32 c); extern void endianswap(void *, int, int);