123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "platform.h"
- #include <algorithm>
- #include "jexcept.hpp"
- #include <assert.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <errno.h>
- #include "jptree.hpp"
- #ifdef _WIN32
- #include "psapi.h"
- #include <eh.h>
- #elif defined (__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <stddef.h>
- #include <errno.h>
- #ifdef __linux__
- #include <execinfo.h> // comment out if not present
- #endif
- #ifdef __APPLE__
- #ifndef _XOPEN_SOURCE
- #define _XOPEN_SOURCE
- #endif
- #include <ucontext.h>
- #endif
- #endif
- //#define NOSEH
- #define NO_LINUX_SEH
- #define EXTENDED_EXCEPTION_TRACE
- #ifdef EXTENDED_EXCEPTION_TRACE
- #include "jmisc.hpp"
- #define LINUX_SIGNAL_EXCEPTION
- #endif
- const char * errorSeverityString[] = {"Information", "Warning", "Error", "Alert", "Ignore", "Fatal", "Unknown"};
- const char * querySeverityString(ErrorSeverity errorSeverity)
- {
- if (errorSeverity<_elements_in(errorSeverityString))
- return errorSeverityString[errorSeverity];
- else
- return errorSeverityString[SeverityUnknown];
- }
- class jlib_thrown_decl StringException: public IException, public CInterface
- {
- public:
- IMPLEMENT_IINTERFACE;
- StringException(int code, const char *str, MessageAudience aud = MSGAUD_user) : errcode(code), msg(str), audience(aud) {};
-
- int errorCode() const { return errcode; }
- StringBuffer & errorMessage(StringBuffer &str) const { str.append(msg); return str;}
- MessageAudience errorAudience() const { return audience; }
- protected:
- int errcode;
- StringAttr msg;
- MessageAudience audience;
- };
- IException *makeStringExceptionVA(int code, const char *format, va_list args)
- {
- StringBuffer eStr;
- eStr.limited_valist_appendf(1024, format, args);
- return new StringException(code, eStr.str());
- }
- IException *makeStringExceptionV(int code,const char *format, ...)
- {
- va_list args;
- va_start(args, format);
- IException *ret = makeStringExceptionVA(code, format, args);
- va_end(args);
- return ret;
- }
- IException jlib_decl *makeStringException(int code,const char *why)
- {
- return new StringException(code,why);
- }
- IException *makeStringExceptionVA(MessageAudience aud, int code, const char *format, va_list args)
- {
- StringBuffer eStr;
- eStr.limited_valist_appendf(1024, format, args);
- return new StringException(code, eStr.str(), aud);
- }
- IException *makeStringExceptionV(MessageAudience aud, int code, const char *format, ...)
- {
- va_list args;
- va_start(args, format);
- IException *ret = makeStringExceptionVA(aud, code, format, args);
- va_end(args);
- return ret;
- }
- IException jlib_decl *makeStringException(MessageAudience aud,int code,const char *why)
- {
- return new StringException(code,why,aud);
- }
- class jlib_thrown_decl WrappedException: public StringException
- {
- typedef StringException PARENT;
- public:
- WrappedException(IException *_exception, int code, const char *str, MessageAudience aud = MSGAUD_user) : StringException(code, str, aud), exception(_exception) { }
- virtual StringBuffer & errorMessage(StringBuffer &str) const override
- {
- PARENT::errorMessage(str);
- if (exception)
- {
- str.appendf("[ %u, ", exception->errorCode());
- exception->errorMessage(str).append(" ]");
- }
- return str;
- }
- protected:
- Linked<IException> exception;
- };
- IException *makeWrappedExceptionVA(IException *e, int code, const char *format, va_list args)
- {
- StringBuffer eStr;
- eStr.limited_valist_appendf(1024, format, args);
- return new WrappedException(e, code, eStr.str());
- }
- IException *makeWrappedExceptionV(IException *e, int code, const char *format, ...)
- {
- va_list args;
- va_start(args, format);
- IException *ret = makeWrappedExceptionVA(e, code, format, args);
- va_end(args);
- return ret;
- }
- void jlib_decl throwStringExceptionV(int code,const char *format, ...)
- {
- va_list args;
- va_start(args, format);
- IException *ret = makeStringExceptionVA(code, format, args);
- va_end(args);
- throw ret;
- }
- class jlib_thrown_decl OsException: public IOSException, public CInterface
- {
- public:
- IMPLEMENT_IINTERFACE;
- OsException(int code) : errcode(code) {};
- OsException(int code, const char *_msg) : msg(_msg), errcode(code) {};
- ~OsException() {}
-
- int errorCode() const { return errcode; }
- StringBuffer & errorMessage(StringBuffer &str) const
- {
- if (msg)
- str.append(msg).append(", ");
- formatSystemError(str, errcode);
- return str;
- }
- MessageAudience errorAudience() const { return MSGAUD_user; }
- protected:
- StringAttr msg;
- int errcode;
- };
- IOSException *makeOsException(int code)
- {
- return new OsException(code);
- }
- IOSException *makeOsException(int code, const char *msg)
- {
- return new OsException(code, msg);
- }
- IOSException *makeOsExceptionV(int code, const char *msg, ...)
- {
- StringBuffer eStr;
- va_list args;
- va_start(args, msg);
- eStr.limited_valist_appendf(1024, msg, args);
- va_end(args);
- return new OsException(code, eStr.str());
- }
- class jlib_thrown_decl ErrnoException: public IErrnoException, public CInterface
- {
- public:
- IMPLEMENT_IINTERFACE;
- ErrnoException(int errn) : audience(MSGAUD_user) { errcode = errn==-1?errno:errn; }
- ErrnoException(int errn, const char *_msg, MessageAudience aud = MSGAUD_user) : msg(_msg), audience(aud) { errcode = errn==-1?errno:errn; }
- ~ErrnoException() { }
-
- int errorCode() const { return errcode; }
- StringBuffer & errorMessage(StringBuffer &str) const
- {
- if (msg)
- str.append(msg).append(", ");
- if (errcode==DISK_FULL_EXCEPTION_CODE)
- str.append("Disk full");
- else
- str.append(strerror(errcode));
- return str;
- }
- MessageAudience errorAudience() const { return audience; }
- protected:
- StringAttr msg;
- int errcode;
- MessageAudience audience;
- };
- IErrnoException *makeErrnoException(int errn, const char *msg)
- {
- return new ErrnoException(errn, msg);
- }
- IErrnoException *makeErrnoException(const char *msg)
- {
- return new ErrnoException(-1, msg);
- }
- IErrnoException *makeErrnoExceptionV(int errn, const char *msg, ...)
- {
- StringBuffer eStr;
- va_list args;
- va_start(args, msg);
- eStr.limited_valist_appendf(1024, msg, args);
- va_end(args);
- return new ErrnoException(errn, eStr.str());
- }
- IErrnoException *makeErrnoExceptionV(const char *msg, ...)
- {
- StringBuffer eStr;
- va_list args;
- va_start(args, msg);
- eStr.limited_valist_appendf(1024, msg, args);
- va_end(args);
- return new ErrnoException(-1, eStr.str());
- }
- IErrnoException *makeErrnoException(MessageAudience aud, int errn, const char *msg)
- {
- return new ErrnoException(errn, msg, aud);
- }
- IErrnoException *makeErrnoExceptionV(MessageAudience aud, int errn, const char *msg, ...)
- {
- StringBuffer eStr;
- va_list args;
- va_start(args, msg);
- eStr.limited_valist_appendf(1024, msg, args);
- va_end(args);
- return new ErrnoException(errn, eStr.str(), aud);
- }
- IErrnoException *makeErrnoExceptionV(MessageAudience aud, const char *msg, ...)
- {
- StringBuffer eStr;
- va_list args;
- va_start(args, msg);
- eStr.limited_valist_appendf(1024, msg, args);
- va_end(args);
- return new ErrnoException(-1, eStr.str(), aud);
- }
- const char* serializeMessageAudience(MessageAudience ma)
- {
- const char* ret;
- switch(ma)
- {
- case MSGAUD_operator: ret = "operator"; break;
- case MSGAUD_user: ret = "user"; break;
- case MSGAUD_programmer: ret = "programmer"; break;
- case MSGAUD_all: ret = "all"; break;
- default: ret = "unknown"; break;
- }
- return ret;
- }
- MessageAudience deserializeMessageAudience(const char* text)
- {
- MessageAudience ma = MSGAUD_programmer;
- if (text && *text)
- {
- if (!strcmp(text, "operator"))
- ma = MSGAUD_operator;
- else if (!strcmp(text, "user"))
- ma = MSGAUD_user;
- else if (!strcmp(text, "programmer"))
- ma = MSGAUD_programmer;
- else if (!strcmp(text, "all"))
- ma = MSGAUD_all;
- }
- return ma;
- }
- class jlib_thrown_decl CMultiException : implements IMultiException, public CInterface
- {
- public:
- IMPLEMENT_IINTERFACE
-
- CMultiException(const char* source=NULL)
- {
- if (source)
- source_.append(source);
- }
-
- //convenience methods for handling this as an array
- virtual aindex_t ordinality() const
- {
- synchronized block(m_mutex);
- return array_.ordinality();
- }
- virtual IException& item(aindex_t pos) const
- {
- synchronized block(m_mutex);
- return array_.item(pos);
- }
- virtual const char* source() const
- {
- synchronized block(m_mutex);
- return source_.str();
- }
-
- //for complete control...caller is responsible for thread safety!
- virtual IArrayOf<IException>& getArray() { return array_; }
-
- //add another exception
- virtual void append(IException& e)
- {
- synchronized block(m_mutex);
- array_.append(e);
- }
- virtual void append(IMultiException& me)
- {
- synchronized block(m_mutex);
-
- IArrayOf<IException>& exceptions = me.getArray();
- const char* source = me.source();
- ForEachItemIn(i, exceptions)
- {
- IException& e = exceptions.item(i);
- if (source && *source)
- {
- StringBuffer msg;
- msg.appendf("[%s] ",source);
- e.errorMessage(msg);
- array_.append(*makeStringExceptionV(e.errorAudience(), e.errorCode(), "%s", msg.str()));
- }
- else
- array_.append(*LINK(&e));
- }
- }
-
-
- StringBuffer& serialize(StringBuffer& buffer, unsigned indent = 0, bool simplified=false, bool root=true) const
- {
- synchronized block(m_mutex);
-
- if (root)
- buffer.append("<Exceptions>");
-
- if (!simplified)
- {
- if (indent) buffer.append("\n\t");
- buffer.appendf("<Source>%s</Source>", source_.str());
- }
-
- ForEachItemIn(i, array_)
- {
- IException& exception = array_.item(i);
-
- if (indent) buffer.append("\n\t");
- buffer.append("<Exception>");
-
- //tag order is important for some soap clients (i.e. Java Axis)
-
- if (indent) buffer.append("\n\t\t");
- buffer.appendf("<Code>%d</Code>", exception.errorCode());
-
- if (indent) buffer.append("\n\t\t");
- buffer.appendf("<Audience>%s</Audience>", serializeMessageAudience( exception.errorAudience() ));
-
- if (simplified)
- {
- if (indent) buffer.append("\n\t\t");
- StringBuffer msg;
- buffer.appendf("<Source>%s</Source>", source_.str());
- }
-
- if (indent) buffer.append("\n\t\t");
-
- StringBuffer msg;
- StringBuffer encoded;
- encodeXML(exception.errorMessage(msg).str(), encoded);
- buffer.appendf("<Message>%s</Message>", encoded.str());
-
- if (indent) buffer.append("\n\t");
- buffer.append("</Exception>");
- }
-
- if (root)
- buffer.append("</Exceptions>");
- return buffer;
- }
- StringBuffer& serializeJSON(StringBuffer& buffer, unsigned indent = 0, bool simplified=false, bool root=true, bool enclose=false) const
- {
- synchronized block(m_mutex);
- if (enclose)
- {
- buffer.append("{");
- if (indent) buffer.append("\n");
- }
- if (root)
- buffer.append("\"Exceptions\": {");
- if (!simplified)
- {
- if (indent) buffer.append("\n\t");
- buffer.appendf("\"Source\": \"%s\"", source_.str());
- }
- ForEachItemIn(i, array_)
- {
- if (i == 0 && !simplified)
- buffer.appendf(", ");
- else if (i > 0)
- buffer.append(", ");
- IException& exception = array_.item(i);
- if (indent) buffer.append("\n\t");
- if (i == 0)
- buffer.append("\"Exception\": [");
- if (indent) buffer.append("\n\t");
- buffer.append("{");
- if (indent) buffer.append("\n\t\t");
- buffer.appendf("\"Code\": %d,", exception.errorCode());
- if (indent) buffer.append("\n\t\t");
- buffer.appendf("\"Audience\": \"%s\",", serializeMessageAudience( exception.errorAudience() ));
- if (!simplified)
- {
- if (indent) buffer.append("\n\t\t");
- buffer.appendf("\"Source\": \"%s\",", source_.str());
- }
- if (indent) buffer.append("\n\t\t");
- StringBuffer msg;
- StringBuffer encoded;
- encodeJSON(encoded, exception.errorMessage(msg).str());
- buffer.appendf("\"Message\": \"%s\"", encoded.str());
- if (indent) buffer.append("\n\t");
- buffer.append("}");
- }
- if (indent) buffer.append("\n\t");
- buffer.append("]");
- if (root)
- {
- if (indent) buffer.append("\n");
- buffer.append("}");
- }
- if (enclose)
- {
- if (indent) buffer.append("\n");
- buffer.append("}");
- }
- return buffer;
- }
- virtual void deserialize(const char* xml)
- {
- synchronized block(m_mutex);
- StringBuffer wrapper;
-
- if (strncmp(xml, "<Exceptions>", 12))
- xml = wrapper.appendf("<Exceptions>%s</Exceptions>", xml).str();
- Owned<IPropertyTree> pTree = createPTreeFromXMLString(xml);
- if (!pTree)
- throw makeStringException(-1, "Failed to deserialize IMultiException!");
- Owned<IPropertyTreeIterator> i = pTree->getElements("Exception");
-
- if (pTree->hasProp("Source"))
- source_.clear().append( pTree->queryProp("Source"));
- else
- {
- if (i->first())
- {
- IPropertyTree* pNode = &i->query();
- source_.clear().append( pNode->queryProp("Source"));
- }
- }
-
- array_.kill();
- ForEach(*i)
- {
- IPropertyTree* pNode = &i->query();
- IException* pException =
- makeStringException(
- deserializeMessageAudience(pNode->queryProp("Audience")),
- pNode->getPropInt("Code", -1),
- pNode->queryProp("Message"));
- array_.append(*pException);
- }
- }
-
- //the following methods override those in IIException
- //
- virtual int errorCode() const
- {
- synchronized block(m_mutex);
- return ordinality() == 1 ? item(0).errorCode() : -1;
- }
- virtual StringBuffer& errorMessage(StringBuffer &msg) const
- {
- synchronized block(m_mutex);
- ForEachItemIn(i, array_)
- {
- IException& e = item(i);
-
- StringBuffer buf;
- msg.appendf("[%3d: %s] ", e.errorCode(), e.errorMessage(buf).str());
- }
- return msg;
- }
- virtual MessageAudience errorAudience() const
- {
- synchronized block(m_mutex);
- return ordinality() == 1 ? item(0).errorAudience() : MSGAUD_programmer;
- }
-
- private:
- CMultiException( const CMultiException& );
- IArrayOf<IException> array_;
- StringBuffer source_;
- mutable Mutex m_mutex;
- };
- IMultiException *makeMultiException(const char* source/*=NULL*/)
- {
- return new CMultiException(source);
- }
- void pexception(const char *msg,IException *e)
- { // like perror except for exceptions
- StringBuffer s;
- fprintf(stderr,"%s : %s\n",msg,e?e->errorMessage(s).str():"NULL Exception!");
- }
- void userBreakpoint()
- {
- #ifdef _WIN32
- try
- {
- DebugBreak();
- }
- catch (...)
- {
- //if not debugging don't give an unhandled exception.
- }
- #endif
- }
- const char *sanitizeSourceFile(const char *file)
- {
- if (file)
- {
- const char *tail = strrchr(file, '/');
- if (tail)
- return tail+1;
- #ifdef _WIN32
- tail = strrchr(file, '\\');
- if (tail)
- return tail+1;
- #endif
- }
- return file;
- }
- void throwUnexpectedException(const char * file, unsigned line)
- {
- printStackReport();
- throw makeStringExceptionV(9999, "Internal Error at %s(%d)", sanitizeSourceFile(file), line);
- }
- void throwUnexpectedException(const char * where, const char * file, unsigned line)
- {
- printStackReport();
- throw makeStringExceptionV(9999, "Internal Error '%s' at %s(%d)", where, sanitizeSourceFile(file), line);
- }
- void raiseAssertException(const char *assertion, const char *file, unsigned line)
- {
- StringBuffer s;
- s.append("assert(");
- s.append(assertion);
- s.append(") failed - file: ");
- s.append(sanitizeSourceFile(file));
- s.append(", line ");
- s.append(line);
- if (queryLogMsgManager())
- {
- printStackReport();
- IERRLOG("%s",s.str()); // make sure doesn't get lost!
- queryLogMsgManager()->flushQueue(10*1000);
- #ifdef _DEBUG
- // cause a breakpoint in the debugger if we are debugging.
- //userBreakpoint();
- #endif
- }
-
- #if 0
- #ifndef USING_MPATROL
- #ifdef _WIN32
- // disable memory leak dump since it is meaningless in this case
- int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
- tmpFlag &= ~_CRTDBG_LEAK_CHECK_DF;
- _CrtSetDbgFlag( tmpFlag );
- #endif
- #endif
- #endif
- throw makeStringException(3000, s.str()); // 3000: internal error
- }
- void raiseAssertCore(const char *assertion, const char *file, unsigned line)
- {
- printStackReport();
- StringBuffer s;
- s.append("assert(");
- s.append(assertion);
- s.append(") failed - file: ");
- s.append(sanitizeSourceFile(file));
- s.append(", line ");
- s.append(line);
- IERRLOG("%s",s.str()); // make sure doesn't get lost!
- queryLogMsgManager()->flushQueue(10*1000);
- #ifdef _WIN32
- userBreakpoint();
- ExitProcess(255);
- #else
- raise(SIGABRT);
- _exit(255);
- #endif
-
- }
- static int SEHnested = 0;
- static IExceptionHandler *SEHHandler = NULL;
- static bool SEHtermOnSystemDLLs = false;
- static bool SEHtermAlways = false;
- #ifdef _WIN32
- static void *SEHrestore;
- #ifdef EXTENDED_EXCEPTION_TRACE
- static LPTSTR GetExceptionString( DWORD dwCode )
- {
- #define EXCEPTION( x ) case EXCEPTION_##x: return #x;
-
- switch ( dwCode )
- {
- EXCEPTION( ACCESS_VIOLATION )
- EXCEPTION( DATATYPE_MISALIGNMENT )
- EXCEPTION( BREAKPOINT )
- EXCEPTION( SINGLE_STEP )
- EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
- EXCEPTION( FLT_DENORMAL_OPERAND )
- EXCEPTION( FLT_DIVIDE_BY_ZERO )
- EXCEPTION( FLT_INEXACT_RESULT )
- EXCEPTION( FLT_INVALID_OPERATION )
- EXCEPTION( FLT_OVERFLOW )
- EXCEPTION( FLT_STACK_CHECK )
- EXCEPTION( FLT_UNDERFLOW )
- EXCEPTION( INT_DIVIDE_BY_ZERO )
- EXCEPTION( INT_OVERFLOW )
- EXCEPTION( PRIV_INSTRUCTION )
- EXCEPTION( IN_PAGE_ERROR )
- EXCEPTION( ILLEGAL_INSTRUCTION )
- EXCEPTION( NONCONTINUABLE_EXCEPTION )
- EXCEPTION( STACK_OVERFLOW )
- EXCEPTION( INVALID_DISPOSITION )
- EXCEPTION( GUARD_PAGE )
- EXCEPTION( INVALID_HANDLE )
- }
-
- static CHAR szBuffer[512] = { 0 };
-
- FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
- GetModuleHandle( "NTDLL.DLL" ),
- dwCode, 0, szBuffer, sizeof( szBuffer ), 0 );
-
- return szBuffer;
- }
- static BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset )
- {
- szModule[0] = 0;
- section = 0;
- offset = 0;
- if ((unsigned)(memsize_t)addr<0x10000)
- return FALSE;
-
-
- MEMORY_BASIC_INFORMATION mbi;
-
- if ( !VirtualQuery( addr, &mbi, sizeof(mbi) ) )
- return FALSE;
-
- memsize_t hMod = (memsize_t)mbi.AllocationBase;
-
- if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
- return FALSE;
-
- PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
-
- PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
-
- PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
-
- memsize_t rva = (memsize_t)addr - hMod;
-
- for (unsigned i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++ )
- {
- DWORD sectionStart = pSection->VirtualAddress;
- DWORD sectionEnd = sectionStart
- + std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
-
- if ( (rva >= sectionStart) && (rva <= sectionEnd) )
- {
- section = i+1;
- offset = (DWORD)(rva - sectionStart);
- return TRUE;
- }
- }
-
- return FALSE;
- }
- #if defined(_WIN32)
- #ifdef __cplusplus
- extern "C" {
- typedef BOOL (CALLBACK* LPENUMPROCESSMODULES)(HANDLE,HMODULE *,DWORD,LPDWORD);
- typedef BOOL (CALLBACK* LPGETMODULEINFORMATION)(HANDLE,HMODULE,LPMODULEINFO,DWORD);
- }
- #endif
- #endif
- static void ModuleWalk()
- {
- HMODULE hmSystem = LoadLibrary("psapi.dll");
- if (!hmSystem)
- return;
- LPENUMPROCESSMODULES enumProcessModules = (LPENUMPROCESSMODULES)GetProcAddress(hmSystem,"EnumProcessModules");
- if (!enumProcessModules)
- return;
- LPGETMODULEINFORMATION getModuleInformation = (LPGETMODULEINFORMATION)GetProcAddress(hmSystem,"GetModuleInformation");
- if (!getModuleInformation)
- return;
- DWORD processID = GetCurrentProcessId();
- DBGLOG("Process ID: %u", processID);
-
- // Get a list of all the modules in this process.
-
- HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
- PROCESS_VM_READ,
- FALSE, processID );
- if (NULL == hProcess)
- return;
-
- HMODULE hMods[1024];
- DWORD cbNeeded;
- if (enumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
- for (unsigned i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) {
- char szModName[MAX_PATH];
- szModName[0] = 0;
- // Get the full path to the module's file.
-
- MODULEINFO modinfo;
- memset(&modinfo,0,sizeof(modinfo));
- getModuleInformation(hProcess, hMods[i], &modinfo, sizeof(modinfo));
- GetModuleFileName( hMods[i], szModName, sizeof(szModName));
- IERRLOG("%8X %8X %8X %s",(unsigned)modinfo.lpBaseOfDll,(unsigned)modinfo.SizeOfImage,(unsigned)modinfo.EntryPoint,szModName);
- }
- }
-
- CloseHandle( hProcess );
- FreeLibrary(hmSystem);
- }
- static void StackWalk( size_t pc, size_t bp )
- {
- IERRLOG( "Call stack:" );
-
- IERRLOG( "Address Frame Logical addr Module" );
-
- size_t * pFrame;
- size_t * pPrevFrame=NULL;
-
- pFrame = (size_t*)bp;
-
- do
- {
- TCHAR szModule[MAX_PATH] = "";
- DWORD section = 0, offset = 0;
-
- if (pc>0x10000)
- GetLogicalAddress((PVOID)pc, szModule,sizeof(szModule),section,offset );
- else
- strcpy(szModule,"NULL");
-
- IERRLOG( "%08X %08X %04X:%08X %s",
- pc, pFrame, section, offset, szModule );
-
- if ( (size_t)pFrame & 0x80000003 )
- break;
-
- if ( (size_t)pFrame <= (size_t)pPrevFrame )
- break;
-
- if ( IsBadWritePtr(pFrame, sizeof(PVOID)*2) )
- break;
-
- pc = pFrame[1];
-
- if ( IsBadCodePtr((FARPROC) pc) )
- break;
-
- pPrevFrame = pFrame;
-
- pFrame = (size_t *)pFrame[0];
-
- } while ( 1 );
- }
- static void doPrintStackReport( size_t ip, size_t _bp, size_t sp )
- {
- if (_bp==0) {
- #ifdef _ARCH_X86_
- __asm {
- mov eax,ebp
- mov _bp,eax
- }
- #else
- IERRLOG("inline assembler is only supported for x86_32; StackReport incomplete bp tend to not be used");
- #endif
- }
-
- for (unsigned i=0;i<8;i++) {
- StringBuffer s;
- #ifdef __64BIT__
- s.appendf("Stack[%016X]:",sp);
- #else
- s.appendf("Stack[%08X]:",sp);
- #endif
- for (unsigned j=0;j<8;j++) {
- if ( IsBadReadPtr((const void *)sp, sizeof(unsigned)) )
- break;
- size_t v = *(size_t *)sp;
- sp += sizeof(unsigned);
- #ifdef __64BIT__
- s.appendf(" %016X",v);
- #else
- s.appendf(" %08X",v);
- #endif
- }
- IERRLOG( "%s",s.str());
- }
-
-
- StackWalk( ip , _bp);
- ModuleWalk();
- StringBuffer threadlist;
- IERRLOG( "ThreadList:\n%s",getThreadList(threadlist).str());
-
- }
- static void PrintExceptionReport( PEXCEPTION_POINTERS pExceptionInfo)
- {
- IERRLOG("=====================================================");
-
-
- PrintMemoryStatusLog();
- PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
-
- IERRLOG( "Exception code: %08X %s",
- pExceptionRecord->ExceptionCode,
- GetExceptionString(pExceptionRecord->ExceptionCode) );
-
- IERRLOG( "Fault address: %08X", pExceptionRecord->ExceptionAddress);
-
- TCHAR szFaultingModule[MAX_PATH];
- DWORD section, offset;
- GetLogicalAddress( pExceptionRecord->ExceptionAddress,
- szFaultingModule,
- sizeof( szFaultingModule ),
- section, offset );
-
- IERRLOG("Fault module: %02X:%08X %s", section, offset, szFaultingModule);
-
- PCONTEXT pCtx = pExceptionInfo->ContextRecord;
-
- IERRLOG( "\nRegisters:" );
-
- #ifdef _ARCH_X86_64_
- IERRLOG("RAX:%016" I64F "X RBX:%016" I64F "X RCX:%016" I64F "X RDX:%016" I64F "X RSI:%016" I64F "X RDI:%016" I64F "X",
- pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx, pCtx->Rsi, pCtx->Rdi );
- IERRLOG("R8: %016" I64F "X R9: %016" I64F "X R10:%016" I64F "X R11:%016" I64F "X R12:%016" I64F "X R13:%016" I64F "X",
- pCtx->R8, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13);
- IERRLOG("R14:%016" I64F "X R15:%016" I64F "X",
- pCtx->R14, pCtx->R15);
- IERRLOG( "CS:RIP:%04X:%016" I64F "X", pCtx->SegCs, pCtx->Rip );
- IERRLOG( "SS:PSP:%04X:%016" I64F "X PBP:%016" I64F "X",
- pCtx->SegSs, pCtx->Rsp, pCtx->Rbp );
- #elif defined(_ARCH_X86_)
- IERRLOG("EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X",
- pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, pCtx->Esi, pCtx->Edi );
-
- IERRLOG( "CS:EIP:%04X:%08X", pCtx->SegCs, pCtx->Eip );
- IERRLOG( "SS:ESP:%04X:%08X EBP:%08X",
- pCtx->SegSs, pCtx->Esp, pCtx->Ebp );
- #else
- // ARMFIX: Implement register bank dump for ARM on _WIN32.
- IERRLOG("Register bank not implemented for your platform");
- #endif
-
- IERRLOG( "DS:%04X ES:%04X FS:%04X GS:%04X",
- pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs );
- IERRLOG( "Flags:%08X", pCtx->EFlags );
- #ifdef _ARCH_X86_64_
- doPrintStackReport(pCtx->Rip, pCtx->Rbp,pCtx->Rsp);
- #elif defined(_ARCH_X86_)
- doPrintStackReport(pCtx->Eip, pCtx->Ebp,pCtx->Esp);
- #else
- // ARMFIX: Implement stack dump for ARM on _WIN32.
- IERRLOG("Stack report not implemented for your platform");
- #endif
- if (SEHtermOnSystemDLLs || SEHtermAlways) {
- char *s = szFaultingModule;
- while (*s) {
- char *sep = strchr(s,'\\');
- if (!sep) {
- sep = strchr(s,'.');
- if (sep)
- *sep = 0;
- break;
- }
- s = sep+1;
- }
- if (SEHtermAlways || (stricmp(s,"ntdll")==0)||(stricmp(s,"kernel32")==0)||(stricmp(s,"msvcrt")==0)||(stricmp(s,"msvcrtd")==0)) {
- TerminateProcess(GetCurrentProcess(), 1);
- }
- }
- }
- class jlib_thrown_decl CSEHException: public ISEH_Exception, public CInterface
- {
- public:
- IMPLEMENT_IINTERFACE;
- CSEHException(unsigned int u, _EXCEPTION_POINTERS* pExp) : errcode((int)u)
- {
- #ifdef EXTENDED_EXCEPTION_TRACE
- PrintExceptionReport(pExp);
- #endif
- #ifdef ALLREGS
- char s[256]; // not too good on stack faults!
- sprintf(s,"SEH Exception(%x)\n"
- "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n"
- "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n"
- "CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X",
- u,
- pExp->ContextRecord->Eax, pExp->ContextRecord->Ebx,
- pExp->ContextRecord->Ecx, pExp->ContextRecord->Edx,
- pExp->ContextRecord->Esi, pExp->ContextRecord->Edi,
- pExp->ContextRecord->Ebp, pExp->ContextRecord->Esp,
- pExp->ContextRecord->Eip, pExp->ContextRecord->EFlags,
- pExp->ContextRecord->SegCs, pExp->ContextRecord->SegDs,
- pExp->ContextRecord->SegSs, pExp->ContextRecord->SegEs,
- pExp->ContextRecord->SegFs, pExp->ContextRecord->SegGs);
- #else
- char s[80];
- #ifdef _ARCH_X86_64_
- sprintf(s,"SEH Exception(%08X) at %04X:%016" I64F "X\n",u,pExp->ContextRecord->SegCs,pExp->ContextRecord->Rip);
- #elif defined(_ARCH_X86_)
- sprintf(s,"SEH Exception(%08X) at %04X:%08X\n",u,pExp->ContextRecord->SegCs,pExp->ContextRecord->Eip);
- #else
- // ARMFIX: Implement exception dump for ARM on _WIN32.
- sprintf(s,"SEH Exception");
- #endif
- #endif
- msg.set(s);
- };
- int errorCode() const { return errcode; }
- StringBuffer & errorMessage(StringBuffer &str) const { str.append(msg); return str;}
- MessageAudience errorAudience() const { return MSGAUD_user; }
- static void Translate(unsigned int u, _EXCEPTION_POINTERS* pExp)
- {
- #ifdef _DEBUG
- if (u == 0x80000003) return; // int 3 breakpoints
- static CriticalSection crit;
- {
- CriticalBlock b(crit);
- PrintExceptionReport(pExp);
- }
- #endif
- ISEH_Exception *e = new CSEHException(u,pExp);
- if (SEHHandler && SEHHandler->fireException(e)) return;
- throw(e);
- }
- protected:
- int errcode;
- StringAttr msg;
- };
- #endif
- #else
- #ifdef LINUX_SIGNAL_EXCEPTION
- #ifndef NO_LINUX_SEH
- static IException *sigsegv_exc;
- #endif
- static int excsignal;
- class jlib_thrown_decl CSEHException: public ISEH_Exception, public CInterface
- {
- public:
- IMPLEMENT_IINTERFACE;
- CSEHException(int signum, const char *s)
- {
- errcode = signum;
- msg.set(s);
- };
- int errorCode() const { return errcode; }
- StringBuffer & errorMessage(StringBuffer &str) const { str.append(msg); return str;}
- MessageAudience errorAudience() const { return MSGAUD_user; }
- protected:
- int errcode;
- StringAttr msg;
- };
- #ifndef NO_LINUX_SEH
- static void throwSigSegV()
- {
- int childpid = fork();
- if (childpid <= 0) { // the child
- // generate a coredump on different process
- signal(excsignal, SIG_DFL);
- raise(excsignal);
- return;
- }
- PROGLOG("Dumping core using child process %d",childpid);
- waitpid(childpid, NULL, 0);
- if (SEHHandler && SEHHandler->fireException(sigsegv_exc))
- return;
- throw sigsegv_exc;
- }
- #endif
- static std::atomic<bool> processAborted { false };
- void jlib_decl setProcessAborted(bool _abortVal)
- {
- processAborted = _abortVal;
- }
- NO_SANITIZE("alignment") void excsighandler(int signum, siginfo_t *info, void *extra)
- {
- static byte nested=0;
- if (nested++)
- return;
- excsignal = 0;
- #if defined(NO_LINUX_SEH)
- // ensure other signals from now on cause exit
- sigset_t blockset;
- sigemptyset(&blockset);
- struct sigaction act;
- act.sa_mask = blockset;
- act.sa_flags = 0;
- act.sa_handler = SIG_DFL;
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGILL, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
- sigaction(SIGFPE, &act, NULL);
- sigaction(SIGABRT, &act, NULL);
- #endif
- StringBuffer s;
- #ifdef _ARCH_X86_64_
- #define I64X "%016" I64F "X"
- ucontext_t *uc = (ucontext_t *)extra;
- #ifdef __APPLE__
- __int64 ip = uc->uc_mcontext->__ss.__rip;
- __int64 sp = uc->uc_mcontext->__ss.__rsp;
- #else
- __int64 ip = uc->uc_mcontext.gregs[REG_RIP];
- __int64 sp = uc->uc_mcontext.gregs[REG_RSP];
- #endif
- excsignal = signum;
- s.appendf("SIG: %s(%d), accessing " I64X ", IP=" I64X, strsignal(signum),signum, (__int64)info->si_addr, ip);
-
- StringBuffer networkIp;
- PROGLOG("================================================");
- PROGLOG("Program: %s:%s", queryHostIP().getIpText(networkIp).str(),queryCurrentProcessPath());
- PROGLOG("Signal: %d %s",signum,strsignal(signum));
- PROGLOG("Fault IP: " I64X "", ip);
- PROGLOG("Accessing: " I64X "", (unsigned __int64) info->si_addr);
- #ifdef _EXECINFO_H
- printStackReport(ip);
- #endif
- PROGLOG("Registers:" );
- #ifdef __APPLE__
- PROGLOG("EAX:" I64X " EBX:" I64X " ECX:" I64X " EDX:" I64X " ESI:" I64X " EDI:" I64X "",
- (unsigned __int64) uc->uc_mcontext->__ss.__rax, (unsigned __int64)uc->uc_mcontext->__ss.__rbx,
- (unsigned __int64) uc->uc_mcontext->__ss.__rcx, (unsigned __int64)uc->uc_mcontext->__ss.__rdx,
- (unsigned __int64) uc->uc_mcontext->__ss.__rsi, (unsigned __int64)uc->uc_mcontext->__ss.__rdi);
- PROGLOG("R8 :" I64X " R9 :" I64X " R10:" I64X " R11:" I64X "",
- (unsigned __int64) uc->uc_mcontext->__ss.__r8, (unsigned __int64)uc->uc_mcontext->__ss.__r9,
- (unsigned __int64) uc->uc_mcontext->__ss.__r10, (unsigned __int64) uc->uc_mcontext->__ss.__r11 );
- PROGLOG("R12:" I64X " R13:" I64X " R14:" I64X " R15:" I64X "",
- (unsigned __int64) uc->uc_mcontext->__ss.__r12, (unsigned __int64)uc->uc_mcontext->__ss.__r13,
- (unsigned __int64) uc->uc_mcontext->__ss.__r14, (unsigned __int64) uc->uc_mcontext->__ss.__r15 );
- PROGLOG( "CS:EIP:%04X:" I64X "", ((unsigned) uc->uc_mcontext->__ss.__cs)&0xffff, ip );
- PROGLOG( " ESP:" I64X " EBP:" I64X "", sp, (unsigned __int64) uc->uc_mcontext->__ss.__rbp );
- #else
- PROGLOG("EAX:" I64X " EBX:" I64X " ECX:" I64X " EDX:" I64X " ESI:" I64X " EDI:" I64X "",
- (unsigned __int64) uc->uc_mcontext.gregs[REG_RAX], (unsigned __int64)uc->uc_mcontext.gregs[REG_RBX],
- (unsigned __int64) uc->uc_mcontext.gregs[REG_RCX], (unsigned __int64) uc->uc_mcontext.gregs[REG_RDX],
- (unsigned __int64) uc->uc_mcontext.gregs[REG_RSI], (unsigned __int64) uc->uc_mcontext.gregs[REG_RDI] );
- PROGLOG("R8 :" I64X " R9 :" I64X " R10:" I64X " R11:" I64X "",
- (unsigned __int64) uc->uc_mcontext.gregs[REG_R8], (unsigned __int64)uc->uc_mcontext.gregs[REG_R9],
- (unsigned __int64) uc->uc_mcontext.gregs[REG_R10], (unsigned __int64) uc->uc_mcontext.gregs[REG_R11] );
- PROGLOG("R12:" I64X " R13:" I64X " R14:" I64X " R15:" I64X "",
- (unsigned __int64) uc->uc_mcontext.gregs[REG_R12], (unsigned __int64)uc->uc_mcontext.gregs[REG_R13],
- (unsigned __int64) uc->uc_mcontext.gregs[REG_R14], (unsigned __int64) uc->uc_mcontext.gregs[REG_R15] );
- PROGLOG( "CS:EIP:%04X:" I64X "", ((unsigned) uc->uc_mcontext.gregs[REG_CSGSFS])&0xffff, ip );
- PROGLOG( " ESP:" I64X " EBP:" I64X "", sp, (unsigned __int64) uc->uc_mcontext.gregs[REG_RBP] );
- #endif
-
- for (unsigned i=0;i<8;i++) {
- StringBuffer s;
- s.appendf("Stack[" I64X "]:",sp);
- for (unsigned j=0;j<8;j++) {
- __int64 v = *(size_t *)sp;
- sp += sizeof(unsigned);
- s.appendf(" " I64X "",v);
- }
- PROGLOG( "%s",s.str());
- }
- #elif defined (__linux__) && defined (_ARCH_X86_)
- ucontext_t *uc = (ucontext_t *)extra;
- unsigned ip = uc->uc_mcontext.gregs[REG_EIP];
- unsigned sp = uc->uc_mcontext.gregs[REG_ESP];
-
- excsignal = signum;
- s.appendf("SIG: %s(%d), accessing %p, IP=%x", strsignal(signum),signum, info->si_addr, ip);
-
- StringBuffer networkIp;
- PROGLOG("================================================");
- PROGLOG("Program: %s:%s", queryHostIP().getIpText(networkIp).str(),queryCurrentProcessPath());
- PROGLOG("Signal: %d %s",signum,strsignal(signum));
- PROGLOG("Fault IP: %08X", ip);
- PROGLOG("Accessing: %08X", (unsigned) info->si_addr);
- #ifdef _EXECINFO_H
- printStackReport(ip);
- #endif
- PROGLOG("Registers:" );
- PROGLOG("EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X",
- uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX],
- uc->uc_mcontext.gregs[REG_ECX], uc->uc_mcontext.gregs[REG_EDX],
- uc->uc_mcontext.gregs[REG_ESI], uc->uc_mcontext.gregs[REG_EDI] );
-
- PROGLOG( "CS:EIP:%04X:%08X", uc->uc_mcontext.gregs[REG_CS], ip );
- PROGLOG( "SS:ESP:%04X:%08X EBP:%08X",
- uc->uc_mcontext.gregs[REG_SS], sp, uc->uc_mcontext.gregs[REG_EBP] );
-
- for (unsigned i=0;i<8;i++) {
- StringBuffer s;
- s.appendf("Stack[%08X]:",sp);
- for (unsigned j=0;j<8;j++) {
- size_t v = *(size_t *)sp;
- sp += sizeof(unsigned);
- s.appendf(" %08X",v);
- }
- PROGLOG( "%s",s.str());
- }
- PROGLOG("Frame:");
- unsigned* bp = (unsigned*) (uc->uc_mcontext.gregs[REG_EBP]);
- for (unsigned n=0; n<64; n++) {
- unsigned * nextbp = (unsigned *) *bp++;
- unsigned fip = *bp;
- if ((fip < 0x08000000) || (fip > 0x7fffffff) || (nextbp < bp))
- break;
- PROGLOG("%2d %08X %08X",n+1,fip,(unsigned) bp);
- bp = nextbp;
- }
- #elif defined (__linux__) && defined (__ARM_ARCH_7A__)
- #pragma message "Implement signal dump for ARMv7-A."
- ucontext_t *uc = (ucontext_t *) extra;
- PROGLOG("================================================");
- PROGLOG("Signal: %d %s",signum,strsignal(signum));
- PROGLOG("Registers:" );
- PROGLOG("r0 :%08lX r1 :%08lX r2 :%08lX r3 :%08lX r4 :%08lX r5 :%08lX",
- uc->uc_mcontext.arm_r0, uc->uc_mcontext.arm_r1, uc->uc_mcontext.arm_r2,
- uc->uc_mcontext.arm_r3, uc->uc_mcontext.arm_r4, uc->uc_mcontext.arm_r5);
- PROGLOG("r6 :%08lX r7 :%08lX r8 :%08lX r9 :%08lX r10:%08lX fp :%08lX",
- uc->uc_mcontext.arm_r6, uc->uc_mcontext.arm_r7, uc->uc_mcontext.arm_r8,
- uc->uc_mcontext.arm_r9, uc->uc_mcontext.arm_r10, uc->uc_mcontext.arm_fp);
- PROGLOG("ip :%08lX sp :%08lX lr :%08lX pc :%08lX",
- uc->uc_mcontext.arm_ip, uc->uc_mcontext.arm_sp, uc->uc_mcontext.arm_lr,
- uc->uc_mcontext.arm_pc);
- PROGLOG("CPSR:%08lX\n", uc->uc_mcontext.arm_cpsr);
- struct flags
- {
- unsigned int Mode:4; // bit 0 - 3
- unsigned int M:1; // bit 4
- unsigned int T:1; // bit 5
- unsigned int F:1; // bit 6
- unsigned int I:1; // bit 7
- unsigned int A:1; // bit 8
- unsigned int E:1; // bit 9
- unsigned int IT1:6; // bit 10 - 15
- unsigned int GE:4; // bit 16 - 19
- unsigned int DNM:4; // bit 20 - 23
- unsigned int J:1; // bit 24
- unsigned int IT2:2; // bit 25 - 26
- unsigned int Q:1; // bit 27
- unsigned int V:1; // bit 28
- unsigned int C:1; // bit 29
- unsigned int Z:1; // bit 30
- unsigned int N:1; // bit 31
- } *flags_p;
- const char *ArmCpuModes[] = {
- // M M[3:0]
- "User", // 1 0000
- "FIQ", // 1 0001
- "IRQ", // 1 0010
- "Supervisor", // 1 0011
- "N/A", // 1 0100
- "N/A", // 1 0101
- "Monitor", // 1 0110
- "Abort", // 1 0111
- "N/A", // 1 1000
- "N/A", // 1 1001
- "Hyp" // 1 1010
- "Undefined", // 1 1011
- "N/A", // 1 1100
- "N/A", // 1 1101
- "N/A", // 1 1110
- "System" // 1 1111
- };
- flags_p = (struct flags *)&uc->uc_mcontext.arm_cpsr;
- PROGLOG("Flags N:%d Z:%d C:%d V:%d Q:%d IT:0x%X J:%d GE:0x%X E:%d A:%d I:%d F:%d T:%d M:0x%X [%s]"
- , flags_p->N, flags_p->Z, flags_p->C, flags_p->V, flags_p->Q
- , (flags_p->IT2 << 6 | flags_p->IT1)
- , flags_p->J, flags_p->GE
- , flags_p->E, flags_p->A, flags_p->I, flags_p->F, flags_p->T, (flags_p->M << 4 | flags_p->Mode)
- , ArmCpuModes[flags_p->Mode]
- );
- PROGLOG("Fault address: %08lX", uc->uc_mcontext.fault_address);
- PROGLOG("Trap no : %08lX", uc->uc_mcontext.trap_no);
- PROGLOG("Error code : %08lX", uc->uc_mcontext.error_code);
- PROGLOG("Old mask : %08lX", uc->uc_mcontext.oldmask);
- unsigned sp = uc->uc_mcontext.arm_sp;
- for (unsigned i=0;i<8;i++)
- {
- StringBuffer s;
- s.appendf("Stack[%08X]:",sp);
- for (unsigned j=0;j<8;j++)
- {
- size_t v = *(size_t *)sp;
- sp += sizeof(unsigned);
- s.appendf(" %08X",v);
- }
- }
- PROGLOG( "%s",s.str());
- #elif defined (__linux__) && defined (__arm__)
- #pragma message "Unknown ARM architecture!"
- PROGLOG("================================================");
- PROGLOG("Signal: %d %s",signum,strsignal(signum));
- PROGLOG("More information unavailable on your platform");
- #else
- // Placeholder for any new HW-SW platform
- #endif
- StringBuffer threadlist;
- PROGLOG( "ThreadList:\n%s",getThreadList(threadlist).str());
- queryLogMsgManager()->flushQueue(10*1000);
- // MCK - really should not return after recv'ing any of these signals
- #ifndef NO_LINUX_SEH
- void (* _P)() = throwSigSegV;
- uc->uc_mcontext.gregs[REG_ESP]-=4;
- uc->uc_mcontext.gregs[REG_EIP] = (unsigned)_P;
- unsigned *spp = (unsigned *)sp;
- *spp = ip;
- sigsegv_exc = new CSEHException(signum,s.str());
- #else
- if (SEHHandler)
- {
- if ( SEHHandler->fireException(new CSEHException(signum,s.str())) )
- return;
- }
- if ( (SIGABRT == signum) && (processAborted) )
- _exit(128 + SIGABRT);
- else
- raise(signum);
- #endif
- nested--;
- }
- #endif
- #endif
- void jlib_decl setTerminateOnSEHInSystemDLLs(bool set)
- {
- SEHtermOnSystemDLLs = set;
- }
- void jlib_decl setTerminateOnSEH(bool set)
- {
- SEHtermAlways = set;
- }
- void *EnableSEHtranslation()
- {
- #ifdef NOSEH
- return NULL;
- #else
- #ifdef _WIN32
- return _set_se_translator( CSEHException::Translate );
- #else
- UNIMPLEMENTED;
- #endif
- #endif
- }
- void jlib_decl *setSEHtoExceptionHandler(IExceptionHandler *handler)
- {
- #ifdef NOSEH
- return NULL;
- #endif
- void *ret = SEHHandler;
- SEHHandler = handler;
- return ret;
- }
- void jlib_decl enableSEHtoExceptionMapping()
- {
- #ifdef NOSEH
- return;
- #endif
- if (SEHnested++)
- return; // already done
- #ifdef _WIN32
- enableThreadSEH();
- SEHrestore = EnableSEHtranslation();
- #else
- struct sigaction act;
- sigset_t blockset;
- sigemptyset(&blockset);
- // defer these for thread in handler
- sigaddset(&blockset, SIGINT);
- sigaddset(&blockset, SIGQUIT);
- sigaddset(&blockset, SIGTERM);
- act.sa_mask = blockset;
- act.sa_flags = SA_SIGINFO;
- #if defined(SA_RESETHAND)
- act.sa_flags |= SA_RESETHAND;
- #endif
- act.sa_sigaction = &excsighandler;
- sigaction(SIGSEGV, &act, NULL);
- #ifndef _DEBUG
- sigaction(SIGILL, &act, NULL);
- #endif
- sigaction(SIGBUS, &act, NULL);
- sigaction(SIGFPE, &act, NULL);
- sigaction(SIGABRT, &act, NULL);
- #endif
- }
- void jlib_decl disableSEHtoExceptionMapping()
- {
- #ifdef NOSEH
- return;
- #endif
- if (--SEHnested)
- return;
- #ifdef _WIN32
- if (SEHrestore) {
- void *restore = SEHrestore;
- SEHrestore = NULL;
- _set_se_translator( (_se_translator_function)restore );
- }
- #else
- sigset_t blockset;
- sigemptyset(&blockset);
- struct sigaction act;
- act.sa_mask = blockset;
- act.sa_flags = 0;
- act.sa_handler = SIG_DFL;
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGILL, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
- sigaction(SIGFPE, &act, NULL);
- sigaction(SIGABRT, &act, NULL);
- #endif
- }
- StringBuffer & formatSystemError(StringBuffer & out, unsigned errcode)
- {
- #ifdef _WIN32
- const char * lpMessageBuffer=NULL;
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- errcode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default
- (LPTSTR) &lpMessageBuffer,
- 0,
- NULL );
- if (lpMessageBuffer) {
- out.append(lpMessageBuffer);
- LocalFree( (void *)lpMessageBuffer );
- }
- else {
- out.append(errcode);
- }
- #else
- int saverr = errno;
- errno = 0;
- const char *errstr = strerror(errcode);
- if (errno==0) {
- out.append(errstr);
- }
- else {
- out.append(errcode);
- }
- errno = saverr;
- #endif
- return out;
- }
- IException * deserializeException(MemoryBuffer & in)
- {
- byte nulle;
- in.read(nulle);
- if (nulle) return NULL;
- int code;
- StringAttr text;
- in.read(code);
- in.read(text);
- return makeStringExceptionV(code, "%s", text.get());
- }
- void jlib_decl serializeException(IException * e, MemoryBuffer & out)
- {
- if (!e)
- out.append((byte)1);
- else
- {
- out.append((byte)0);
- StringBuffer text;
- out.append(e->errorCode());
- out.append(e->errorMessage(text).str());
- }
- }
- void printStackReport(__int64 startIP)
- {
- if (!queryLogMsgManager())
- return;
- #ifdef _WIN32
- unsigned onstack=1234;
- doPrintStackReport(0, 0,(unsigned)&onstack);
- #elif defined(__linux__)
- DBGLOG("Backtrace:");
- void *btarray[100];
- unsigned btn = backtrace (btarray, 100);
- char **strings = backtrace_symbols (btarray, btn);
- unsigned i;
- unsigned firstReal = 0;
- if (startIP)
- {
- VStringBuffer iptext("[%p]", (void *) startIP);
- for (i=0; i<btn; i++)
- {
- if (strstr(strings[i], iptext) != nullptr)
- {
- firstReal = i;
- break;
- }
- }
- }
- for (i=firstReal; i<btn; i++)
- DBGLOG(" %s", strings[i]);
- free (strings);
- #endif
- queryLogMsgManager()->flushQueue(10*1000);
- }
- //---------------------------------------------------------------------------------------------------------------------
- unsigned getCommandOutput(StringBuffer &output, const char *cmd, const char *cmdTitle, const char *allowedPrograms)
- {
- Owned<IPipeProcess> pipe = createPipeProcess(allowedPrograms);
- if (pipe->run(cmdTitle, cmd, nullptr, false, true, false))
- {
- Owned<ISimpleReadStream> pipeReader = pipe->getOutputStream();
- readSimpleStream(output, *pipeReader);
- }
- return pipe->wait();
- }
- //---------------------------------------------------------------------------------------------------------------------
- bool getDebuggerGetStacksCmd(StringBuffer &output)
- {
- #ifndef __linux__
- return false; // unsupported
- #endif
- const char *exePath = queryCurrentProcessPath();
- if (!exePath)
- {
- output.append("Unable to capture stacks");
- return false;
- }
- return output.appendf("gdb --batch -n -ex 'thread apply all bt' %s %u", exePath, GetCurrentProcessId());
- }
- bool getAllStacks(StringBuffer &output)
- {
- StringBuffer cmd;
- if (!getDebuggerGetStacksCmd(cmd))
- return false;
- return 0 == getCommandOutput(output, cmd, "get stacks");
- }
- //---------------------------------------------------------------------------------------------------------------------
- class jlib_decl CError : public CInterfaceOf<IError>
- {
- public:
- CError(WarnErrorCategory _category,ErrorSeverity _severity, int _no, const char* _msg, const char* _filename, int _lineno, int _column, int _position, unsigned _activity, const char * _scope);
- virtual int errorCode() const override { return no; }
- virtual StringBuffer & errorMessage(StringBuffer & ret) const override { return ret.append(msg); }
- virtual MessageAudience errorAudience() const override { return MSGAUD_user; }
- virtual const char* getFilename() const override { return filename; }
- virtual WarnErrorCategory getCategory() const override { return category; }
- virtual int getLine() const override { return lineno; }
- virtual int getColumn() const override { return column; }
- virtual int getPosition() const override { return position; }
- virtual StringBuffer& toString(StringBuffer&) const override;
- virtual ErrorSeverity getSeverity() const override { return severity; }
- virtual IError * cloneSetSeverity(ErrorSeverity _severity) const override;
- virtual unsigned getActivity() const override { return activity; }
- virtual const char * queryScope() const override { return scope; }
- virtual IPropertyTree * toTree() const override;
- protected:
- ErrorSeverity severity;
- WarnErrorCategory category;
- int no;
- StringAttr msg;
- StringAttr filename;
- StringAttr scope;
- int lineno;
- int column;
- int position;
- unsigned activity;
- };
- CError::CError(WarnErrorCategory _category, ErrorSeverity _severity, int _no, const char* _msg, const char* _filename, int _lineno, int _column, int _position, unsigned _activity, const char * _scope)
- : severity(_severity), category(_category), msg(_msg), filename(_filename), scope(_scope), activity(_activity)
- {
- no = _no;
- lineno = _lineno;
- column = _column;
- position = _position;
- }
- StringBuffer& CError::toString(StringBuffer& buf) const
- {
- buf.append(filename);
- if(lineno && column)
- buf.append('(').append(lineno).append(',').append(column).append(')');
- buf.append(" : ");
- buf.append(no).append(": ").append(msg);
- return buf;
- }
- IPropertyTree * CError::toTree() const
- {
- Owned<IPropertyTree> xml = createPTree("exception", ipt_fast);
- xml->setPropInt("@severity", severity);
- xml->setPropInt("@category", category);
- xml->setPropInt("@code", no);
- xml->setProp("@msg", msg);
- xml->setProp("@filename", filename);
- xml->setProp("@scope", scope);
- if (lineno)
- xml->setPropInt("@line", lineno);
- if (column)
- xml->setPropInt("@column", column);
- if (position)
- xml->setPropInt("@pos", position);
- if (activity)
- xml->setPropInt("@activity", activity);
- return xml.getClear();
- }
- IError * CError::cloneSetSeverity(ErrorSeverity newSeverity) const
- {
- return new CError(category, newSeverity,
- errorCode(), msg, filename,
- getLine(), getColumn(), getPosition(), getActivity(), queryScope());
- }
- ErrorSeverity queryDefaultSeverity(WarnErrorCategory category)
- {
- if (category == CategoryError)
- return SeverityFatal;
- if (category == CategoryInformation)
- return SeverityInformation;
- if (category == CategoryMistake)
- return SeverityError;
- return SeverityWarning;
- }
- IError *createError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, const char * filename, int lineno, int column, int pos, unsigned activity, const char * scope)
- {
- return new CError(category,severity,errNo,msg,filename,lineno,column,pos, activity, scope);
- }
- IError *createError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, unsigned activity, const char * scope)
- {
- return new CError(category,severity,errNo,msg,nullptr, 0, 0, 0, activity, scope);
- }
- IError *createError(IPropertyTree * tree)
- {
- return new CError((WarnErrorCategory)tree->getPropInt("@category"),
- (ErrorSeverity)tree->getPropInt("@severity"),
- tree->getPropInt("@code"),
- tree->queryProp("@msg"),
- tree->queryProp("@filename"),
- tree->getPropInt("@line"),
- tree->getPropInt("@column"),
- tree->getPropInt("@pos"),
- tree->getPropInt("@activity"),
- tree->queryProp("@scope"));
- }
- //---------------------------------------------------------------------------------------------------------------------
- void IErrorReceiver::ThrowStringException(int code,const char *format, ...) const
- {
- va_list args;
- va_start(args, format);
- IException *ret = MakeStringExceptionVA(code, format, args);
- va_end(args);
- throw ret;
- }
- void IErrorReceiver::reportError(int errNo, const char *msg, const char *filename, int lineno, int column, int position)
- {
- Owned<IError> err = createError(errNo,msg,filename,lineno,column,position);
- report(err);
- }
- void IErrorReceiver::reportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int position)
- {
- ErrorSeverity severity = queryDefaultSeverity(category);
- Owned<IError> warn = createError(category, severity,warnNo,msg,filename,lineno,column,position);
- report(warn);
- }
- const LogMsgCategory & mapToLogMsgCategory(ErrorSeverity severity, MessageAudience aud)
- {
- switch (severity)
- {
- case SeverityIgnore:
- case SeverityInformation:
- {
- switch (aud)
- {
- case MSGAUD_operator:
- return MCoperatorInfo;
- case MSGAUD_user:
- return MCuserInfo;
- case MSGAUD_audit:
- return MCauditInfo;
- default:
- return MCdebugInfo;
- }
- }
- case SeverityAlert:
- case SeverityWarning:
- {
- switch (aud)
- {
- case MSGAUD_operator:
- return MCoperatorWarning;
- case MSGAUD_user:
- return MCuserWarning;
- case MSGAUD_audit:
- return MCauditWarning;
- default:
- return MCinternalWarning;
- }
- }
- case SeverityFatal:
- case SeverityError:
- {
- switch (aud)
- {
- case MSGAUD_operator:
- return MCoperatorError;
- case MSGAUD_user:
- return MCuserError;
- case MSGAUD_audit:
- return MCauditError;
- default:
- return MCinternalError;
- }
- }
- }
- return MCdebugInfo;
- }
- //---------------------------------------------------------------------------------------------------------------------
|