diff --git a/extras/Hadrons/Exceptions.cc b/extras/Hadrons/Exceptions.cc index 1ff26afe..6d5a3dc2 100644 --- a/extras/Hadrons/Exceptions.cc +++ b/extras/Hadrons/Exceptions.cc @@ -48,6 +48,9 @@ using namespace Grid; using namespace Hadrons; using namespace Exceptions; +// backtrace cache +std::vector Grid::Hadrons::Exceptions::backtraceStr; + // logic errors CTOR_EXC(Logic, logic_error(msg + ERR_SUFF)) CTOR_EXC(Definition, Logic("definition error: " + msg, loc)) @@ -82,6 +85,15 @@ void Grid::Hadrons::Exceptions::abort(const std::exception& e) << std::endl; } LOG(Error) << e.what() << std::endl; + if (!backtraceStr.empty()) + { + LOG(Error) << "-- BACKTRACE --------------" << std::endl; + for (auto &s: backtraceStr) + { + LOG(Error) << s << std::endl; + } + LOG(Error) << "---------------------------" << std::endl; + } LOG(Error) << "Aborting program" << std::endl; Grid_finalize(); diff --git a/extras/Hadrons/Exceptions.hpp b/extras/Hadrons/Exceptions.hpp index 38bee8c1..6893ef03 100644 --- a/extras/Hadrons/Exceptions.hpp +++ b/extras/Hadrons/Exceptions.hpp @@ -30,16 +30,39 @@ See the full license in the file "LICENSE" in the top level distribution directo #define Hadrons_Exceptions_hpp_ #include +#include #ifndef Hadrons_Global_hpp_ #include #endif #define HADRONS_SRC_LOC std::string(__FUNCTION__) + " at " \ + std::string(__FILE__) + ":" + std::to_string(__LINE__) +#define HADRONS_BACKTRACE_MAX 128 +#ifdef HAVE_EXECINFO_H +#define HADRONS_CACHE_BACKTRACE \ +{\ + void* _callstack[HADRONS_BACKTRACE_MAX];\ + int _i, _frames = backtrace(_callstack, HADRONS_BACKTRACE_MAX);\ + char** _strs = backtrace_symbols(_callstack, _frames);\ + Grid::Hadrons::Exceptions::backtraceStr.clear();\ + for (_i = 0; _i < _frames; ++_i)\ + {\ + Hadrons::Exceptions::backtraceStr.push_back(std::string(_strs[_i]));\ + }\ + free(_strs);\ +} +#else +#define HADRONS_CACHE_BACKTRACE \ +Grid::Hadrons::Exceptions::backtraceStr.clear();\ +Grid::Hadrons::Exceptions::backtraceStr.push_back(""); +#endif + #define HADRONS_ERROR(exc, msg)\ +HADRONS_CACHE_BACKTRACE \ throw(Exceptions::exc(msg, HADRONS_SRC_LOC)); #define HADRONS_ERROR_REF(exc, msg, address)\ +HADRONS_CACHE_BACKTRACE \ throw(Exceptions::exc(msg, HADRONS_SRC_LOC, address)); #define DECL_EXC(name, base) \ @@ -60,6 +83,9 @@ BEGIN_HADRONS_NAMESPACE namespace Exceptions { + // backtrace cache + extern std::vector backtraceStr; + // logic errors DECL_EXC(Logic, std::logic_error); DECL_EXC(Definition, Logic);