set(base_SOURCES
application.cpp application.thpp array.cpp context.cpp
- convert.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
+ convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp logger.cpp logger.thpp
netstring.cpp networkstream.cpp object.cpp objectlock.cpp process.cpp
qstring.cpp ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp
bool Application::m_RequestReopenLogs = false;
pid_t Application::m_ReloadProcess = 0;
static bool l_Restarting = false;
+static bool l_InExceptionHandler = false;
int Application::m_ArgC;
char **Application::m_ArgV;
double Application::m_StartTime;
*/
void Application::ExceptionHandler(void)
{
+ if (l_InExceptionHandler)
+ for (;;)
+ Utility::Sleep(5);
+
+ l_InExceptionHandler = true;
+
#ifndef _WIN32
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
#ifdef _WIN32
LONG CALLBACK Application::SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS exi)
{
+ if (l_InExceptionHandler)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ l_InExceptionHandler = true;
+
DisplayInfoMessage();
std::cerr << "Caught unhandled SEH exception." << std::endl
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include "base/convert.hpp"
#include <fstream>
}
}
}
+
+std::string icinga::to_string(const errinfo_debuginfo& e)
+{
+ std::ostringstream msgbuf;
+ msgbuf << "Config location: " << e.value() << "\n";
+ ShowCodeFragment(msgbuf, e.value(), true);
+ return msgbuf.str();
+}
+
#ifndef DEBUGINFO_H
#define DEBUGINFO_H
-#include "config/i2-config.hpp"
+#include "base/i2-base.hpp"
#include "base/qstring.hpp"
+#include "base/exception.hpp"
namespace icinga
{
};
};
-I2_CONFIG_API std::ostream& operator<<(std::ostream& out, const DebugInfo& val);
+I2_BASE_API std::ostream& operator<<(std::ostream& out, const DebugInfo& val);
-I2_CONFIG_API DebugInfo DebugInfoRange(const DebugInfo& start, const DebugInfo& end);
+I2_BASE_API DebugInfo DebugInfoRange(const DebugInfo& start, const DebugInfo& end);
-I2_CONFIG_API void ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbose);
+I2_BASE_API void ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbose);
+
+struct errinfo_debuginfo_;
+typedef boost::error_info<struct errinfo_debuginfo_, DebugInfo> errinfo_debuginfo;
+
+std::string to_string(const errinfo_debuginfo& e);
}
return DynamicType::GetByName(GetTypeName());
}
+DebugInfo DynamicObject::GetDebugInfo(void) const
+{
+ return m_DebugInfo;
+}
+
+void DynamicObject::SetDebugInfo(const DebugInfo& di)
+{
+ m_DebugInfo = di;
+}
+
bool DynamicObject::IsActive(void) const
{
return GetActive();
#include "base/object.hpp"
#include "base/serializer.hpp"
#include "base/dictionary.hpp"
+#include "base/debuginfo.hpp"
#include <boost/signals2.hpp>
#include <map>
shared_ptr<DynamicType> GetType(void) const;
+ DebugInfo GetDebugInfo(void) const;
+ void SetDebugInfo(const DebugInfo& di);
+
bool IsActive(void) const;
bool IsPaused(void) const;
private:
static DynamicObject::Ptr GetObject(const String& type, const String& name);
static void RestoreObject(const String& message, int attributeTypes);
+
+ DebugInfo m_DebugInfo;
};
#define DECLARE_TYPENAME(klass) \
#include "base/serializer.hpp"
#include "base/debug.hpp"
#include "base/objectlock.hpp"
+#include "base/convert.hpp"
using namespace icinga;
if (it->second == object)
return;
- BOOST_THROW_EXCEPTION(std::runtime_error("RegisterObject() found existing object with the same name: " + name));
+ BOOST_THROW_EXCEPTION(user_error("An object with type '" + m_Name + "' and name '" + name + "' already exists (" +
+ Convert::ToString(it->second->GetDebugInfo()) + "), new declaration: " + Convert::ToString(object->GetDebugInfo()))
+ << errinfo_debuginfo(object->GetDebugInfo()));
}
m_ObjectMap[name] = object;
return boost::diagnostic_information(eptr);
}
+user_error::user_error(void)
+{ }
+
+user_error::user_error(const String& message)
+ : m_Message(message)
+{ }
+
+user_error::~user_error(void) throw()
+{ }
+
+const char *user_error::what(void) const throw()
+{
+ return m_Message.CStr();
+}
+
namespace icinga
{
-class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception { };
+class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception {
+public:
+ user_error(void);
+ user_error(const String& message);
+ ~user_error(void) throw();
+
+ const char *what(void) const throw();
+
+private:
+ String m_Message;
+};
I2_BASE_API StackTrace *GetLastExceptionStack(void);
I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
aexpression.cpp applyrule.cpp base-type.conf base-type.cpp
configcompilercontext.cpp configcompiler.cpp configerror.cpp configitembuilder.cpp
configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS}
- configtype.cpp debuginfo.cpp objectrule.cpp typerule.cpp typerulelist.cpp
+ configtype.cpp objectrule.cpp typerule.cpp typerulelist.cpp
)
if(ICINGA2_UNITY_BUILD)
#define AEXPRESSION_H
#include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include "base/array.hpp"
#include "base/dictionary.hpp"
#include "config/i2-config.hpp"
#include "config/aexpression.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include <boost/function.hpp>
namespace icinga
#define CONFIGCOMPILER_H
#include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include "base/registry.hpp"
#include "base/initialize.hpp"
#include "base/singleton.hpp"
#define CONFIGCOMPILERCONTEXT_H
#include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include <boost/thread/mutex.hpp>
#include <vector>
using namespace icinga;
ConfigError::ConfigError(const String& message)
- : m_Message(message)
+ : user_error(message)
{ }
-ConfigError::~ConfigError(void) throw()
-{ }
-
-const char *ConfigError::what(void) const throw()
-{
- return m_Message.CStr();
-}
-
-std::string icinga::to_string(const errinfo_debuginfo& e)
-{
- std::ostringstream msgbuf;
- msgbuf << "Config location: " << e.value() << "\n";
- ShowCodeFragment(msgbuf, e.value(), true);
- return msgbuf.str();
-}
#define CONFIGERROR_H
#include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include "base/exception.hpp"
namespace icinga
{
public:
ConfigError(const String& message);
- ~ConfigError(void) throw();
-
- const char *what(void) const throw();
-
-private:
- String m_Message;
};
-struct errinfo_debuginfo_;
-typedef boost::error_info<struct errinfo_debuginfo_, DebugInfo> errinfo_debuginfo;
-
-std::string to_string(const errinfo_debuginfo& e);
-
}
#endif /* CONFIGERROR_H */
#include "config/applyrule.hpp"
#include "config/objectrule.hpp"
#include "config/configtype.hpp"
+#include "config/configerror.hpp"
#include "base/application.hpp"
#include "base/dynamictype.hpp"
#include "base/objectlock.hpp"
if (!dtype)
BOOST_THROW_EXCEPTION(std::runtime_error("Type '" + GetType() + "' does not exist."));
- if (dtype->GetObject(GetName()))
- BOOST_THROW_EXCEPTION(std::runtime_error("An object with type '" + GetType() + "' and name '" + GetName() + "' already exists."));
-
if (IsAbstract())
return DynamicObject::Ptr();
}
DynamicObject::Ptr dobj = dtype->CreateObject(properties);
+ dobj->SetDebugInfo(m_DebugInfo);
dobj->Register();
m_Object = dobj;
#ifndef CONFIGITEMBUILDER_H
#define CONFIGITEMBUILDER_H
-#include "config/debuginfo.hpp"
#include "config/aexpression.hpp"
#include "config/configitem.hpp"
+#include "base/debuginfo.hpp"
#include "base/object.hpp"
namespace icinga
#include "config/i2-config.hpp"
#include "config/aexpression.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
#include "base/dynamictype.hpp"
namespace icinga
\r
#include "config/i2-config.hpp"\r
#include "config/typerulelist.hpp"\r
-#include "config/debuginfo.hpp"\r
+#include "base/debuginfo.hpp"\r
\r
namespace icinga\r
{\r