Commit 1a1de05a authored by silvan's avatar silvan

Re-structured exceptions and moved PHASIC::Flavour_Order declaration into header

parent 34bdb6c2
......@@ -2,7 +2,7 @@
#include "AHADIC++/Tools/Hadronisation_Parameters.H"
#include "AHADIC++/Tools/Constituents.H"
#include "ATOOLS/Math/Random.H"
#include "ATOOLS/Org/Message.H"
#include "ATOOLS/Org/Exception.H"
#include <cassert>
using namespace AHADIC;
......
#include "AMISIC++/Main/MI_Base.H"
#include "ATOOLS/Phys/Particle.H"
#include "ATOOLS/Org/Message.H"
#include "ATOOLS/Org/Exception.H"
using namespace AMISIC;
......
......@@ -9,7 +9,7 @@
#include "ATOOLS/Org/File_IO_Base.H"
#include "ATOOLS/Phys/Particle_List.H"
#include "ATOOLS/Phys/Blob_List.H"
#include "ATOOLS/Org/Exception.H"
#include "ATOOLS/Org/Terminator_Objects.H"
#include <map>
namespace PHASIC { class Process_Base; }
......
......@@ -7,6 +7,7 @@
#include "ATOOLS/Org/MyStrStream.H"
#include "BEAM/Main/Beam_Base.H"
#include "ATOOLS/Math/Random.H"
#include "ATOOLS/Org/Exception.H"
using namespace AMISIC;
using namespace ATOOLS;
......
......@@ -4,7 +4,7 @@
#include <fstream>
#include <stddef.h>
#include "ATOOLS/Math/MathTools.H"
#include "ATOOLS/Org/Exception.H"
#include "ATOOLS/Org/Terminator_Objects.H"
#include "ATOOLS/Org/Getter_Function.H"
namespace ATOOLS {
......
#include "ATOOLS/Org/Exception.H"
#include "ATOOLS/Math/MathTools.H"
#include <iostream>
#include <typeinfo>
using namespace ATOOLS;
std::ostream &ATOOLS::operator<<(std::ostream &str,const ex::type &type)
{
switch (type) {
case ex::normal_exit : return str<<"normal exit";
case ex::unknown_option : return str<<"unknown option";
case ex::inconsistent_option : return str<<"inconsistent option";
case ex::not_implemented : return str<<"not implemented";
case ex::critical_error : return str<<"critical error";
case ex::fatal_error : return str<<"fatal error";
case ex::missing_input : return str<<"missing input";
case ex::missing_module : return str<<"missing module";
case ex::unknown : return str<<"unknown exception";
}
return str;
}
Tester_Object::~Tester_Object()
{
}
bool Tester_Object::ApproveTerminate()
{
msg_Error()<<METHOD<<"() ["<<typeid(this).name()
<<"]: Virtual function called !"<<std::endl;
exh->GenerateStackTrace(std::cout);
return true;
}
Terminator_Object::~Terminator_Object()
{
}
bool Terminator_Object::ReadInStatus(const std::string &path)
{
return true;
}
void Terminator_Object::PrepareTerminate()
Exception::Exception(const std::string& type,
const std::string& info,
const std::string& cmethod):
m_info(info), m_type(type)
{
msg_Error()<<METHOD<<"() ["<<typeid(this).name()
<<"]: Virtual function called !"<<std::endl;
}
Exception::Exception(const std::string info):
m_type(ex::fatal_error),
m_info(info)
{
exh->m_exception=this;
}
Exception::Exception(const ex::type type,const std::string info):
m_type(type),
m_info(info)
{
exh->m_exception=this;
}
Exception::Exception(const ex::type type,const std::string info,
std::string cmethod):
m_type(type),
m_info(info)
{
cmethod=cmethod.substr(0,ATOOLS::Min(cmethod.length(),cmethod.find("(")));
std::string cmethod_
=cmethod.substr(0,ATOOLS::Min(cmethod.length(),cmethod.find("(")));
size_t pos;
while ((pos=cmethod.find(" "))!=std::string::npos)
cmethod=cmethod.substr(pos+1);
pos=cmethod.find("::");
while ((pos=cmethod_.find(" "))!=std::string::npos)
cmethod_=cmethod_.substr(pos+1);
pos=cmethod_.find("::");
while (pos!=std::string::npos) {
m_class=cmethod.substr(0,pos);
cmethod=cmethod.substr(pos+2);
pos=cmethod.find("::");
m_method=cmethod.substr(0,ATOOLS::Min(cmethod.length(),pos));
m_class=cmethod_.substr(0,pos);
cmethod_=cmethod_.substr(pos+2);
pos=cmethod_.find("::");
m_method=cmethod_.substr(0,ATOOLS::Min(cmethod_.length(),pos));
}
exh->m_exception=this;
}
Exception::Exception(const ex::type type,const std::string info,
const std::string cclass,const std::string cmethod):
m_type(type),
m_info(info),
m_class(cclass),
m_method(cmethod)
std::ostream &ATOOLS::operator<<(std::ostream &str,
const Exception &exception)
{
exh->m_exception=this;
}
str<<om::bold<<om::red
<<exception.TypeName()<<om::reset
<<om::bold<<" thrown" <<om::reset;
Exception::~Exception()
{
if (exh->m_exception==this) {
msg_Error()<<*this<<std::endl;
exh->SetExitCode();
exh->m_exception=NULL;
}
}
if (exception.m_class.length()>0)
str <<om::bold<< " in "<<om::reset
<<om::blue
<<exception.m_class<<"::"
<<exception.m_method
<<om::reset;
std::ostream &ATOOLS::operator<<(std::ostream &str,const Exception &exception)
{
str<<om::bold<<"Sherpa";
if (exception.m_class.length()>0) {
str<<": "<<om::reset<<om::blue<<exception.m_class
<<"::"<<exception.m_method;
}
return str<<om::reset<<" throws "<<om::bold<<om::red
<<exception.m_type<<om::reset<<om::bold<<": "<<std::endl<<" "<<om::reset<<om::red
<<exception.m_info<<om::reset;
}
str<<":\n"<<om::red
<<exception.m_info
<<om::reset;
return str;
}
......@@ -6,131 +6,108 @@
namespace ATOOLS {
struct ex {
enum type {
normal_exit = 1,
unknown_option = 2,
inconsistent_option = 3,
not_implemented = 4,
critical_error = 5,
fatal_error = 6,
missing_input = 7,
missing_module = 8,
unknown = 0
};
friend std::ostream &operator<<(std::ostream &str,const ex::type &type);
};// end of struct ex
std::ostream &operator<<(std::ostream &str,const ex::type &type);
class Exception_Handler;
class Tester_Object {
protected:
virtual bool ApproveTerminate();
friend class Exception_Handler;
public:
class Exception {
// destructor
virtual ~Tester_Object();
private:
};// end of class Tester_Object
std::string m_info, m_class, m_method, m_type;
class Terminator_Object {
protected:
virtual bool ReadInStatus(const std::string &path);
virtual void PrepareTerminate();
friend class Exception_Handler;
const std::string& TypeName() const { return m_type; }
public:
// destructor
virtual ~Terminator_Object();
Exception(const std::string& name="",
const std::string& info="",
const std::string& cmethod="");
};// end of class Terminator_Object
~Exception() {}
class Exception {
private:
friend std::ostream &operator<<(std::ostream &str,
const Exception &exception);
ex::type m_type;
std::string m_info, m_class, m_method;
};
friend class Exception_Handler;
class normal_exit : public Exception {
public:
normal_exit(const std::string info,
std::string cmethod)
: Exception("Normal exit",
info, cmethod) {}
};
class inconsistent_option : public Exception {
public:
inconsistent_option(const std::string info,
std::string cmethod)
: Exception("Inconsistent option",
info, cmethod) {}
};
class not_implemented : public Exception {
public:
not_implemented(const std::string info,
std::string cmethod)
: Exception("Not implemented",
info, cmethod) {}
};
// constructors
Exception(const std::string info);
Exception(const ex::type type,const std::string info);
Exception(const ex::type type,const std::string info,
std::string cmethod);
Exception(const ex::type type,const std::string info,
const std::string cclass,const std::string cmethod);
class critical_error : public Exception {
public:
critical_error(const std::string info,
std::string cmethod)
: Exception("Critical error",
info, cmethod) {}
};
// destructor
~Exception();
class fatal_error : public Exception {
public:
fatal_error(const std::string info,
std::string cmethod)
: Exception("Fatal error",
info, cmethod) {}
};
// inline functions
inline void SetClass(const std::string cclass) { m_class=cclass; }
inline void SetMethod(const std::string cmethod) { m_method=cmethod; }
class missing_module : public Exception {
public:
missing_module(const std::string info,
std::string cmethod)
: Exception("Missing module",
info, cmethod) {}
};
inline const std::string &Class() const { return m_class; }
inline const std::string &Method() const { return m_method; }
inline const std::string &Info() const { return m_info; }
inline ex::type Type() const { return m_type; }
class missing_input : public Exception {
public:
missing_input(const std::string info,
std::string cmethod)
: Exception("Missing intput",
info, cmethod) {}
};
friend std::ostream &operator<<(std::ostream &str,
const Exception &exception);
class numerical_instability : public Exception {
public:
numerical_instability(const std::string info,
std::string cmethod)
: Exception("Numerical instability",
info, cmethod) {}
};
};// end of class Exception
std::ostream &operator<<(std::ostream &str,const Exception &exception);
/*!
\class Exception
\brief Provides exception handling
This class provides exception handling. Each exception thrown
within Sherpa is caught by a catch (Exception exception) in Main.C.
The appropriate way to include exception throwing into the code
is as follows
\code
using namespace ATOOLS;
...
void Example_Class::Example_Function()
{
...
// explicit call of constructor
throw(ex::normal_exit,"normal abort",
"Example_Class","Example_Function");
// call of constructor through #define directive
THROW(normal_exit,"normal abort");
...
}
\endcode
*/
}// end of namespace ATOOLS
}
#if defined(__sgi) || defined(__GNUC__)
#define THROW(exception,message) \
throw(ATOOLS::Exception(ATOOLS::ex::exception, \
message,__PRETTY_FUNCTION__));
#define THROW(exception,message) \
throw(ATOOLS::exception(message,__PRETTY_FUNCTION__));
#else
#define THROW(exception,message) \
throw(ATOOLS::Exception(ATOOLS::ex::exception,message, \
"<unknown class>::<unknown function>"));
throw(ATOOLS::exception(message,"<unknown class>::<unknown function>"));
#endif
#include "ATOOLS/Org/Exception_Handler.H"
#include "ATOOLS/Org/Stacktrace.H"
#define DO_STACK_TRACE ATOOLS::exh->GenerateStackTrace(std::cout)
#define DO_STACK_TRACE ATOOLS::GenerateStackTrace(std::cout)
#endif
......@@ -22,7 +22,7 @@ libToolsOrg_la_SOURCES = \
Getter_Function.C \
My_MPI.C \
Exception.C \
Exception_Handler.C \
Terminator_Objects.C \
My_File.C \
File_IO_Base.C \
Read_Write_Base.C \
......@@ -32,6 +32,7 @@ libToolsOrg_la_SOURCES = \
Run_Parameter.C \
MyTiming.C \
Message.C \
Stacktrace.C \
IO_Handler.C \
Info_Key.C \
Integration_Info.C \
......@@ -55,7 +56,7 @@ localinc_HEADERS = \
Getter_Function.C \
My_MPI.H \
Exception.H \
Exception_Handler.H \
Terminator_Objects.H \
My_File.H \
File_IO_Base.H \
Read_Write_Base.H \
......@@ -66,6 +67,7 @@ localinc_HEADERS = \
My_Limits.H \
Run_Parameter.H \
Message.H \
Stacktrace.H \
MyTiming.H \
IO_Handler.H \
MyStrStream.H \
......
......@@ -197,7 +197,7 @@ void Run_Parameter::Init(std::string path,std::string file)
msg->SetMPIMode(reader.Get<int>("MPI_OUTPUT",0));
msg->SetPrecision(reader.Get<size_t>("OUTPUT_PRECISION",6));
if (msg->LevelIsInfo())
msg_Out()<<"Welcome to "<<exh->ProgramName()<<", "<<gen.m_username
msg_Out()<<"Welcome to Sherpa, "<<gen.m_username
<<" on "<<gen.m_hostname
<<". Initialization of framework underway."<<std::endl;
msg_Info()<<"The local time is "<<rpa->gen.Timer().TimeString(0)<<"."<<std::endl;
......@@ -355,8 +355,6 @@ void Run_Parameter::Init(std::string path,std::string file)
msg_Info()<<METHOD<<"(): Setting memory limit to "
<<lims.rlim_cur/double(1<<30)<<" GB."<<std::endl;
#endif
int stacktrace = reader.Get<int>("STACK_TRACE",1);
exh->SetStackTrace(stacktrace);
gen.m_accu = reader.Get<double>("NUM_ACCURACY", 1.e-10);
gen.m_sqrtaccu = sqrt(gen.m_accu);
if (gen.m_seeds[1]>0) {
......
#include "ATOOLS/Org/Stacktrace.H"
#include "ATOOLS/Org/Message.H"
#include "ATOOLS/Org/Shell_Tools.H"
#include <iomanip>
#define USING_Stack_Trace
#ifndef __USE_GNU
#ifdef __GNUC__
#define __USE_GNU
#ifdef ARCH_DARWIN
#undef USING_Stack_Trace
#endif
#else
#undef USING_Stack_Trace
#endif
#endif
#ifdef USING_Stack_Trace
#include <execinfo.h>
#include <dlfcn.h>
#define MAX_BACKTRACE_DEPTH 128
#endif
void ATOOLS::GenerateStackTrace(std::ostream &ostr,
const bool endline,
const std::string &comment)
{
#ifdef USING_Stack_Trace
ostr<<comment<<om::bold<<"GenerateStackTrace(..): "
<<om::reset<<om::blue<<"Generating stack trace "
<<om::reset<<om::bold<<"\n{"<<om::reset<<std::endl;
// adapted from root version 3.10 TUnixSystem.cxx
void *trace[MAX_BACKTRACE_DEPTH];
int depth=backtrace(trace,MAX_BACKTRACE_DEPTH);
for (int n=0; n<depth;++n) {
unsigned long addr=(unsigned long)trace[n];
Dl_info info;
if (dladdr(trace[n],&info) && info.dli_fname && info.dli_fname[0]) {
unsigned long symaddr=(unsigned long)info.dli_saddr;
if (symaddr==(unsigned long)NULL) continue;
const char *symname=info.dli_sname;
if (!info.dli_sname || !info.dli_sname[0]) symname="<unknown function>";
// if (!msg->LevelIsDebugging()) {
// if (std::string(symname).find
// ("Exception_Handler")!=std::string::npos ||
// std::string(symname).find
// ("HandleSignal")!=std::string::npos) continue;
// }
std::string linfo;
unsigned long libaddr=(unsigned long)info.dli_fbase;
unsigned long offset=(addr>=libaddr)?addr-libaddr:libaddr-libaddr;
char cmd[4096];
sprintf(cmd,"addr2line -se %s 0x%016lx 2>/dev/null",
info.dli_fname,offset);
if (FILE *pf=popen(cmd,"r")) {
char buf[2048];
if (fgets(buf,2048,pf)) {
linfo=buf;
linfo=linfo.substr(0,linfo.length()-1);
}
if (linfo=="??:0") {
pclose(pf);
sprintf(cmd,"addr2line -se %s 0x%016lx 2>/dev/null",
info.dli_fname,addr);
pf=popen(cmd,"r");
if (fgets(buf,2048,pf)) {
linfo=buf;
linfo=linfo.substr(0,linfo.length()-1);
}
if (linfo=="??:0") linfo="";
}
pclose(pf);
}
ostr<<comment<<" "<<std::setiosflags(std::ios::left)
<<std::setw(15)<<trace[n]<<std::dec
<<" in '"<<om::red<<Demangle(symname)<<om::reset<<"' ";
if (linfo!="") ostr<<"("<<om::lblue<<linfo<<om::reset<<")";
ostr<<"\n";
if (msg->LevelIsDebugging()) ostr<<" from '"<<
om::brown<<info.dli_fname<<om::reset<<"'\n";
ostr<<std::flush;
if (std::string(info.dli_sname)=="main") break;
}
else {
ostr<<comment<<" "<<addr<<" in <unknown function>"<<std::endl;
}
}
ostr<<comment<<om::bold<<"}"<<om::reset;
if (endline) ostr<<std::endl;
#endif
}
#ifndef ATOOLS_Org_Stacktrace_H
#define ATOOLS_Org_Stacktrace_H
#include <iostream>
namespace ATOOLS {
void GenerateStackTrace(std::ostream &ostr,
const bool endline=true,
const std::string &comment="");
}
#endif
#include "ATOOLS/Org/Exception.H"
#include "ATOOLS/Org/Terminator_Objects.H"
#include "ATOOLS/Org/Run_Parameter.H"
#include "ATOOLS/Org/Message.H"
#include "ATOOLS/Org/MyStrStream.H"
#include "ATOOLS/Org/Shell_Tools.H"
#include "ATOOLS/Org/My_MPI.H"
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
using namespace ATOOLS;
ATOOLS::Terminator_Object_Handler *ATOOLS::exh(NULL);
void ATOOLS::Terminate()
{
exh->Terminate(1);
}
Terminator_Object_Handler::Terminator_Object_Handler():
m_noremove(false),
m_nbus(0), m_nsegv(0)
{
std::set_terminate(ATOOLS::Terminate);
std::set_unexpected(ATOOLS::Terminate);
signal(SIGSEGV,ATOOLS::HandleSignal);
signal(SIGINT,ATOOLS::HandleSignal);
signal(SIGPIPE,ATOOLS::HandleSignal);
signal(SIGBUS,ATOOLS::HandleSignal);
signal(SIGFPE,ATOOLS::HandleSignal);
signal(SIGABRT,ATOOLS::HandleSignal);
signal(SIGTERM,ATOOLS::HandleSignal);
signal(SIGXCPU,ATOOLS::HandleSignal);
signal(SIGUSR1,ATOOLS::HandleSignal);
}
bool Terminator_Object_Handler::ReadInStatus(const std::string &path)
{
bool success(true);
msg_Info()<<METHOD<<"(): Reading status from '"<<path<<"' {"<<std::endl;
for (size_t i=0;i<m_terminatorobjects.size();++i)
if (!m_terminatorobjects[i]->ReadInStatus(path)) success=false;
msg_Info()<<"}"<<std::endl;
return success;
}
void Terminator_Object_Handler::PrepareTerminate()
{
static size_t trials=0;
if (++trials>3) Abort(1);
msg_Tracking()<<"Terminator_Object_Handler::PrepareTerminate(): "
<<"Preparing termination ..."<<std::endl;
while (m_terminatorobjects.size()>0) {
m_noremove=true;
m_terminatorobjects.back()->PrepareTerminate();
m_noremove=false;
std::vector<Terminator_Object*>::iterator end=m_terminatorobjects.end();
RemoveTerminatorObject(*--end);
}
while (m_terminatorfunctions.size()>0) {
m_noremove=true;
m_terminatorfunctions.back()();
m_noremove=false;
std::vector<Terminator_Function>::iterator end=m_terminatorfunctions.end();
RemoveTerminatorFunction(*--end);
}
msg_Tracking()<<"... prepared."<<std::endl;
}
void Terminator_Object_Handler::Terminate(unsigned int excode)
{
PrepareTerminate();
rpa->gen.WriteCitationInfo();
msg_Error()<<om::bold<<"Terminator_Object_Handler::Exit: "
<<om::reset<<om::blue<<"Exiting Sherpa with code "
<<om::reset<<om::bold<<"("
<<om::red<<excode<<om::reset<<om::bold<<")"
<<om::reset<<tm::curon<<std::endl;
exit(excode);
}
void Terminator_Object_Handler::AddTerminatorFunction(void (*function)(void))
{
m_terminatorfunctions.push_back(function);
}
void Terminator_Object_Handler::AddTerminatorObject(Terminator_Object *const object)
{
m_terminatorobjects.push_back(object);
}
void Terminator_Object_Handler::
RemoveTerminatorObject(Terminator_Object *const terminatorobject)
{
if (m_noremove) return;
for (std::vector<Terminator_Object*>::iterator
toit=m_terminatorobjects.begin();
toit!=m_terminatorobjects.end();) {
if (*toit==terminatorobject) toit=m_terminatorobjects.erase(toit);
else ++toit;
}
}
void Terminator_Object_Handler::RemoveTerminatorFunction(void (*function)(void))
{
if (m_noremove) return;
for (std::vector<Terminator_Function>::iterator
tfit=m_terminatorfunctions.begin();
tfit!=m_terminatorfunctions.end();) {
if (*tfit==function) tfit=m_terminatorfunctions.erase(tfit);
else ++tfit;
}
}
Terminator_Object_Handler::~Terminator_Object_Handler()
{
}
void ATOOLS::HandleSignal(int signal)
{
exh->HandleSignal(signal);
}
void Terminator_Object_Handler::HandleSignal(int signal)
{
msg_Error()<<std::endl<<om::bold<<"Terminator_Object_Handler::HandleSignal: "
<<om::reset<<om::blue<<"Signal "<<om::reset<<om::bold
<<"("<<om::red<<signal<<om::reset<<om::bold<<")"
<<om::reset<<om::blue<<" caught. "<<om::reset<<std::endl;
if (signal!=SIGINT)
{
GenerateStackTrace(msg->Error());
rpa->gen.SetVariable
("SHERPA_STATUS_PATH",rpa->gen.Variable("SHERPA_RUN_PATH")+
"/Status__"+rpa->gen.Timer().TimeString(3));
msg_Error()<<METHOD<<"(): Pre-crash status saved to:\n'"
<<rpa->gen.Variable("SHERPA_STATUS_PATH")<<"'\n"<<std::endl;
MakeDir(rpa->gen.Variable("SHERPA_STATUS_PATH"));
}
switch (signal) {
case SIGSEGV:
++m_nsegv;
GenerateStackTrace(std::cout,false);
if (m_nsegv>3) {
msg_Error()<<om::reset<<" Abort immediately."<<om::reset<<std::endl;