12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739 |
- /*##############################################################################
- 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
- 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;
- }
- 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);
- sigaction(SIGILL, &act, NULL);
- 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);
- }
- //---------------------------------------------------------------------------------------------------------------------
|