]> granicus.if.org Git - icinga2/commitdiff
Implemented stacktrace support for Windows.
authorGunnar Beutner <gunnar@beutner.name>
Thu, 7 Mar 2013 14:00:26 +0000 (15:00 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Thu, 7 Mar 2013 14:00:26 +0000 (15:00 +0100)
17 files changed:
lib/base/Makefile.am
lib/base/application.cpp
lib/base/application.h
lib/base/base.vcxproj
lib/base/base.vcxproj.filters
lib/base/eventqueue.cpp
lib/base/i2-base.h
lib/base/stacktrace.cpp [new file with mode: 0644]
lib/base/stacktrace.h [new file with mode: 0644]
lib/base/unix.h
lib/base/utility.cpp
lib/base/utility.h
lib/icinga/host.cpp
lib/icinga/icinga.vcxproj.filters
lib/icinga/icingaapplication.cpp
lib/icinga/service-check.cpp
lib/icinga/service.cpp

index be5b2a30086a60d81f7c80a5610ed7f0a7ca40da..a8fadf2e649cc4931bbc82b813ba5d29e2fcc1a0 100644 (file)
@@ -58,6 +58,8 @@ libbase_la_SOURCES =  \
        scripttask.h \
        socket.cpp \
        socket.h \
+       stacktrace.cpp \
+       stacktrace.h \
        stdiostream.cpp \
        stdiostream.h \
        stream.cpp \
index 92f839a4885d3d62680b1beb8b235f86eb6e91be..6f9add2bcc4ab479b6e15c9f87ec1b6865487778 100644 (file)
@@ -308,10 +308,12 @@ void Application::SigAbrtHandler(int signum)
 {
        assert(signum == SIGABRT);
 
+#ifndef _WIN32
        struct sigaction sa;
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = SIG_DFL;
        sigaction(SIGABRT, &sa, NULL);
+#endif /* _WIN32 */
 
        std::cerr << "Caught SIGABRT." << std::endl;
 
@@ -358,13 +360,27 @@ void Application::ExceptionHandler(void)
                          << std::endl;
        }
 
-       Utility::PrintStacktrace(std::cerr, 1);
+       StackTrace trace;
+       trace.Print(std::cerr, 1);
 
        DisplayBugMessage();
 
        abort();
 }
 
+#ifdef _WIN32
+LONG CALLBACK Application::SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS exi)
+{
+       std::cerr << "Unhandled SEH exception." << std::endl;
+
+       StackTrace trace(exi);
+       trace.Print(std::cerr, 1);
+
+       DisplayBugMessage();
+
+       return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif /* _WIN32
 
 /**
  * Installs the exception handlers.
@@ -378,6 +394,8 @@ void Application::InstallExceptionHandlers(void)
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = &Application::SigAbrtHandler;
        sigaction(SIGABRT, &sa, NULL);
+#else /* _WIN32 */
+       SetUnhandledExceptionFilter(&Application::SEHUnhandledExceptionFilter);
 #endif /* _WIN32 */
 }
 
index 08352dac517ce5741229acae7154d869d6e662d0..a7c7929582321c4461413c1279a2c7c1fa7b45b1 100644 (file)
@@ -101,13 +101,14 @@ private:
 
 #ifndef _WIN32
        static void SigIntHandler(int signum);
-       static void SigAbrtHandler(int signum);
 #else /* _WIN32 */
        static BOOL WINAPI CtrlHandler(DWORD type);
+       static LONG WINAPI SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS exi);
 #endif /* _WIN32 */
 
        static void DisplayBugMessage(void);
 
+       static void SigAbrtHandler(int signum);
        static void ExceptionHandler(void);
 
        static void TimeWatchThreadProc(void);
index 2b5afb228f71017fc4b7884076c7236ee4f10770..fcff863a1ed1ab4864f64a73dc13359d0a7fd001 100644 (file)
@@ -20,6 +20,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="application.cpp" />
+    <ClCompile Include="attribute.cpp" />
     <ClCompile Include="component.cpp" />
     <ClCompile Include="connection.cpp" />
     <ClCompile Include="convert.cpp" />
@@ -47,6 +48,7 @@
     <ClCompile Include="scriptfunction.cpp" />
     <ClCompile Include="scripttask.cpp" />
     <ClCompile Include="socket.cpp" />
+    <ClCompile Include="stacktrace.cpp" />
     <ClCompile Include="stdiostream.cpp" />
     <ClCompile Include="stream.cpp" />
     <ClCompile Include="streamlogger.cpp" />
@@ -62,6 +64,7 @@
   <ItemGroup>
     <ClInclude Include="application.h" />
     <ClInclude Include="asynctask.h" />
+    <ClInclude Include="attribute.h" />
     <ClInclude Include="component.h" />
     <ClInclude Include="connection.h" />
     <ClInclude Include="convert.h" />
@@ -70,6 +73,7 @@
     <ClInclude Include="dynamictype.h" />
     <ClInclude Include="eventqueue.h" />
     <ClInclude Include="fifo.h" />
+    <ClInclude Include="stacktrace.h" />
     <ClInclude Include="stdiostream.h" />
     <ClInclude Include="stream.h" />
     <ClInclude Include="netstring.h" />
     <Link>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MTd.lib;ssleay32MTd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>dbghelp.lib;ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MTd.lib;ssleay32MTd.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Lib>
       <AdditionalDependencies>ws2_32.lib;shlwapi.lib</AdditionalDependencies>
     <Link>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MTd.lib;ssleay32MTd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>dbghelp.lib;ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MTd.lib;ssleay32MTd.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Lib>
       <AdditionalDependencies>ws2_32.lib;shlwapi.lib</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MT.lib;ssleay32MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>dbghelp.lib;ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MT.lib;ssleay32MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Lib>
       <AdditionalDependencies>ws2_32.lib;shlwapi.lib</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MT.lib;ssleay32MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>dbghelp.lib;ws2_32.lib;shlwapi.lib;mmatch.lib;cJSON.lib;libeay32MT.lib;ssleay32MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Lib>
       <AdditionalDependencies>ws2_32.lib;shlwapi.lib</AdditionalDependencies>
index 097c74493c5f29e9af1115cbec278cdabb4f4998..4bdbda5f1eb215077e51de3534ba0c010aa300cc 100644 (file)
     <ClCompile Include="eventqueue.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="attribute.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="stacktrace.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="application.h">
     <ClInclude Include="eventqueue.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="attribute.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="stacktrace.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Quelldateien">
index f959dfd190badd5e58c6922d02afd033fe7d6729..921310e0317827fb5e3775e4a3a40c2b17028a78 100644 (file)
@@ -94,16 +94,20 @@ void EventQueue::QueueThreadProc(void)
 
                BOOST_FOREACH(const Callback& ev, events) {
 #ifdef _DEBUG
+                       double st = Utility::GetTime();
+
+#      ifdef RUSAGE_THREAD
                        struct rusage usage_start, usage_end;
 
-                       double st = Utility::GetTime();
                        (void) getrusage(RUSAGE_THREAD, &usage_start);
+#      endif /* RUSAGE_THREAD */
 #endif /* _DEBUG */
 
                        ev();
 
 #ifdef _DEBUG
                        double et = Utility::GetTime();
+#      ifdef RUSAGE_THREAD
                        (void) getrusage(RUSAGE_THREAD, &usage_end);
 
                        double duser = (usage_end.ru_utime.tv_sec - usage_start.ru_utime.tv_sec) +
@@ -119,10 +123,15 @@ void EventQueue::QueueThreadProc(void)
 
                        int dvctx = usage_end.ru_nvcsw - usage_start.ru_nvcsw;
                        int divctx = usage_end.ru_nivcsw - usage_start.ru_nivcsw;
-
+#      endif /* RUSAGE_THREAD */
                        if (et - st > 0.5) {
                                stringstream msgbuf;
+#      ifdef RUSAGE_THREAD
                                msgbuf << "Event call took user:" << duser << "s, system:" << dsys << "s, wait:" << dwait << "s, minor_faults:" << dminfaults << ", major_faults:" << dmajfaults << ", voluntary_csw:" << dvctx << ", involuntary_csw:" << divctx;
+#      else
+                               msgbuf << "Event call took " << (et - st) << "s";
+#      endif /* RUSAGE_THREAD */
+
                                Logger::Write(LogWarning, "base", msgbuf.str());
                        }
 #endif /* _DEBUG */
index 04ef5aff44a33959abda81e0370562d1ae86ac11..b55bc9388b174ddc658450d79e8bcbaf37d0a691 100644 (file)
@@ -77,6 +77,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <signal.h>
 
 #include <string>
 #include <exception>
@@ -191,6 +192,7 @@ namespace signals2 = boost::signals2;
 
 #include "qstring.h"
 #include "utility.h"
+#include "stacktrace.h"
 #include "object.h"
 #include "objectlock.h"
 #include "exception.h"
diff --git a/lib/base/stacktrace.cpp b/lib/base/stacktrace.cpp
new file mode 100644 (file)
index 0000000..a08e5bc
--- /dev/null
@@ -0,0 +1,161 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program is free software; you can redistribute it and/or              *
+ * modify it under the terms of the GNU General Public License                *
+ * as published by the Free Software Foundation; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * This program is distributed in the hope that it will be useful,            *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
+ * GNU General Public License for more details.                               *
+ *                                                                            *
+ * You should have received a copy of the GNU General Public License          *
+ * along with this program; if not, write to the Free Software Foundation     *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
+ ******************************************************************************/
+
+#include "i2-base.h"
+#if HAVE_BACKTRACE_SYMBOLS
+#      include <execinfo.h>
+#endif /* HAVE_BACKTRACE_SYMBOLS */
+
+using namespace icinga;
+
+boost::once_flag StackTrace::m_OnceFlag = BOOST_ONCE_INIT;
+
+#ifdef _MSC_VER
+#      pragma optimize("", off)
+#endif /* _MSC_VER */
+
+StackTrace::StackTrace(void)
+{
+       boost::call_once(m_OnceFlag, &StackTrace::Initialize);
+
+#if HAVE_BACKTRACE_SYMBOLS
+       m_Count = backtrace(m_Frames, sizeof(m_Frames) / sizeof(m_Frames[0]));
+#else /* HAVE_BACKTRACE_SYMBOLS */
+#      ifdef _WIN32
+       m_Count = CaptureStackBackTrace(0, sizeof(m_Frames) / sizeof(m_Frames), m_Frames, NULL);
+#      else /* _WIN32 */
+       m_Count = 0;
+#      endif /* _WIN32 */
+#endif /* HAVE_BACKTRACE_SYMBOLS */
+}
+
+#ifdef _MSC_VER
+#      pragma optimize("", on)
+#endif /* _MSC_VER */
+
+#ifdef _WIN32
+StackTrace::StackTrace(PEXCEPTION_POINTERS exi)
+{
+       boost::call_once(m_OnceFlag, &StackTrace::Initialize);
+
+       STACKFRAME64 frame;
+       int architecture;
+
+#ifdef _WIN64
+       architecture = IMAGE_FILE_MACHINE_AMD64;
+
+       frame.AddrPC.Offset = exi->ContextRecord->Rip;
+       frame.AddrFrame.Offset = exi->ContextRecord->Rbp;
+       frame.AddrStack.Offset = exi->ContextRecord->Rsp;
+#else /* _WIN64 */
+       architecture = IMAGE_FILE_MACHINE_I386;
+
+       frame.AddrPC.Offset = exi->ContextRecord->Eip;
+       frame.AddrFrame.Offset = exi->ContextRecord->Ebp;
+       frame.AddrStack.Offset = exi->ContextRecord->Esp;
+#endif  /* _WIN64 */
+
+       frame.AddrPC.Mode = AddrModeFlat;
+       frame.AddrFrame.Mode = AddrModeFlat;
+       frame.AddrStack.Mode = AddrModeFlat;
+
+       m_Count = 0;
+
+       while (StackWalk64(architecture, GetCurrentProcess(), GetCurrentThread(),
+           &frame, exi->ContextRecord, NULL, &SymFunctionTableAccess64,
+           &SymGetModuleBase64, NULL) && m_Count < sizeof(m_Frames) / sizeof(m_Frames[0])) {
+               m_Frames[m_Count] = reinterpret_cast<void *>(frame.AddrPC.Offset);
+               m_Count++;
+       }
+}
+#endif /* _WIN32 */
+
+void StackTrace::Initialize(void)
+{
+       (void) SymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
+       (void) SymInitialize(GetCurrentProcess(), NULL, TRUE);
+}
+
+/**
+ * Prints a stacktrace to the specified stream.
+ *
+ * @param fp The stream.
+ * @param ignoreFrames The number of stackframes to ignore (in addition to
+ *                    the one this function is executing in).
+ * @returns true if the stacktrace was printed, false otherwise.
+ */
+void StackTrace::Print(ostream& fp, int ignoreFrames)
+{
+       fp << std::endl << "Stacktrace:" << std::endl;
+
+#ifndef _WIN32
+#      if HAVE_BACKTRACE_SYMBOLS
+       char **messages = backtrace_symbols(m_Frames, m_Count);
+
+       for (int i = ignoreFrames + 1; i < m_Count && messages != NULL; ++i) {
+               String message = messages[i];
+
+               char *sym_begin = strchr(messages[i], '(');
+
+               if (sym_begin != NULL) {
+                       char *sym_end = strchr(sym_begin, '+');
+
+                       if (sym_end != NULL) {
+                               String sym = String(sym_begin + 1, sym_end);
+                               String sym_demangled = Utility::DemangleSymbolName(sym);
+
+                               if (sym_demangled.IsEmpty())
+                                       sym_demangled = "<unknown function>";
+
+                               message = String(messages[i], sym_begin) + ": " + sym_demangled + " (" + String(sym_end);
+                       }
+               }
+
+               fp << "\t(" << i - ignoreFrames - 1 << ") " << message << std::endl;
+       }
+
+       free(messages);
+
+       fp << std::endl;
+
+       return true;
+#      else /* HAVE_BACKTRACE_SYMBOLS */
+       fp << "(not available)" << std::endl;
+#      endif /* HAVE_BACKTRACE_SYMBOLS */
+#else /* _WIN32 */
+       for (int i = ignoreFrames + 1; i < m_Count; i++) {
+               char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+               PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
+               pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+               pSymbol->MaxNameLen = MAX_SYM_NAME;
+
+               DWORD64 dwAddress = (DWORD64)m_Frames[i];
+               DWORD dwDisplacement;
+               DWORD64 dwDisplacement64;
+
+               IMAGEHLP_LINE64 line;
+               line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+
+               (void) SymGetLineFromAddr64(GetCurrentProcess(), dwAddress, &dwDisplacement, &line);
+               (void) SymFromAddr(GetCurrentProcess(), dwAddress, &dwDisplacement64, pSymbol);
+
+               fp << "\t(" << i - ignoreFrames - 1 << ") " << line.FileName << ":" << line.LineNumber << ": " << pSymbol->Name << "+" << dwDisplacement64 << std::endl;
+       }
+#endif /* _WIN32 */
+}
diff --git a/lib/base/stacktrace.h b/lib/base/stacktrace.h
new file mode 100644 (file)
index 0000000..a25994a
--- /dev/null
@@ -0,0 +1,52 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program is free software; you can redistribute it and/or              *
+ * modify it under the terms of the GNU General Public License                *
+ * as published by the Free Software Foundation; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * This program is distributed in the hope that it will be useful,            *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
+ * GNU General Public License for more details.                               *
+ *                                                                            *
+ * You should have received a copy of the GNU General Public License          *
+ * along with this program; if not, write to the Free Software Foundation     *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
+ ******************************************************************************/
+
+#ifndef STACKTRACE_H
+#define STACKTRACE_H
+
+namespace icinga
+{
+
+/**
+ * A stacktrace.
+ *
+ * @ingroup base
+ */
+class StackTrace
+{
+public:
+       StackTrace(void);
+#ifdef _WIN32
+       StackTrace(PEXCEPTION_POINTERS exi);
+#endif /* _WIN32 */
+
+       void Print(ostream& fp, int ignoreFrames = 0);
+
+private:
+       void *m_Frames[64];
+       int m_Count;
+
+       static boost::once_flag m_OnceFlag;
+
+       static void Initialize(void);
+};
+
+}
+
+#endif /* UTILITY_H */
index 25a83ddea880eaf725f5a7b77cabaca4a1677055..de72451b2c02693b15d4fed4ca7efd8ef0a0c504 100644 (file)
@@ -30,7 +30,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <pthread.h>
-#include <signal.h>
 #include <libgen.h>
 #include <syslog.h>
 #include <sys/file.h>
index ad7726a5bf86458d8a5414e05dfaec31be804ad6..1165cf629581aeded2b3f368892aa7aa62263956 100644 (file)
@@ -19,9 +19,6 @@
 
 #include "i2-base.h"
 #include <mmatch.h>
-#if HAVE_BACKTRACE_SYMBOLS
-#      include <execinfo.h>
-#endif /* HAVE_BACKTRACE_SYMBOLS */
 
 using namespace icinga;
 
@@ -61,55 +58,7 @@ String Utility::GetTypeName(const type_info& ti)
        return DemangleSymbolName(ti.name());
 }
 
-/**
- * Prints a stacktrace to the specified stream.
- *
- * @param fp The stream.
- * @param ignoreFrames The number of stackframes to ignore (in addition to
- *                    the one this function is executing in).
- * @returns true if the stacktrace was printed, false otherwise.
- */
-bool Utility::PrintStacktrace(ostream& fp, int ignoreFrames)
-{
-#if HAVE_BACKTRACE_SYMBOLS
-       void *frames[50];
-       int framecount = backtrace(frames, sizeof(frames) / sizeof(frames[0]));
-
-       char **messages = backtrace_symbols(frames, framecount);
-
-       fp << std::endl << "Stacktrace:" << std::endl;
-
-       for (int i = ignoreFrames + 1; i < framecount && messages != NULL; ++i) {
-               String message = messages[i];
-
-               char *sym_begin = strchr(messages[i], '(');
-
-               if (sym_begin != NULL) {
-                       char *sym_end = strchr(sym_begin, '+');
 
-                       if (sym_end != NULL) {
-                               String sym = String(sym_begin + 1, sym_end);
-                               String sym_demangled = Utility::DemangleSymbolName(sym);
-
-                               if (sym_demangled.IsEmpty())
-                                       sym_demangled = "<unknown function>";
-
-                               message = String(messages[i], sym_begin) + ": " + sym_demangled + " (" + String(sym_end);
-                       }
-               }
-
-               fp << "\t(" << i - ignoreFrames - 1 << ") " << message << std::endl;
-       }
-
-       free(messages);
-
-       fp << std::endl;
-
-       return true;
-#else /* HAVE_BACKTRACE_SYMBOLS */
-       return false;
-#endif /* HAVE_BACKTRACE_SYMBOLS */
-}
 
 /**
  * Detaches from the controlling terminal.
index f9017659279f91a20becd09653283438a8f5ae50..9035f2945d978b94417bff539236f25562d63c65 100644 (file)
@@ -33,7 +33,6 @@ class I2_BASE_API Utility
 public:
        static String DemangleSymbolName(const String& sym);
        static String GetTypeName(const type_info& ti);
-       static bool PrintStacktrace(ostream& fp, int ignoreFrames = 0);
 
        static void Daemonize(void);
 
index 0e62d4a1d7e075b2320d687e9cbb9ce2dc4f20a6..f3776473a45955a7820ff939e3c80624fe1226f3 100644 (file)
@@ -508,8 +508,6 @@ set<Service::Ptr> Host::GetParentServices(void) const
 
 HostState Host::GetState(void) const
 {
-       assert(!OwnsLock());
-
        if (!IsReachable())
                return HostUnreachable;
 
@@ -594,19 +592,7 @@ Dictionary::Ptr Host::CalculateDynamicMacros(void) const
                macros->Set("HOSTNAME", GetName());
                macros->Set("HOSTDISPLAYNAME", GetDisplayName());
                macros->Set("HOSTALIAS", GetName());
-
-               HostState state = GetState();
-
-               macros->Set("HOSTSTATE", HostStateToString(GetState()));
-               macros->Set("HOSTSTATEID", GetState());
-
-               HostState lastState = GetLastState();
-               StateType lastStateType = GetLastStateType();
-
-               macros->Set("LASTHOSTSTATE", HostStateToString(lastState));
-               macros->Set("LASTHOSTSTATEID", lastState);
-               macros->Set("LASTHOSTSTATETYPE", Service::StateTypeToString(lastStateType));
-               }
+       }
 
        Dictionary::Ptr cr;
 
@@ -615,11 +601,16 @@ Dictionary::Ptr Host::CalculateDynamicMacros(void) const
        if (hc) {
                ObjectLock olock(hc);
 
+               macros->Set("HOSTSTATE", HostStateToString(GetState()));
+               macros->Set("HOSTSTATEID", GetState());
                macros->Set("HOSTSTATETYPE", Service::StateTypeToString(hc->GetStateType()));
                macros->Set("HOSTATTEMPT", hc->GetCurrentCheckAttempt());
                macros->Set("MAXHOSTATTEMPT", hc->GetMaxCheckAttempts());
 
-               macros->Set("LASTHOSTSTATECHANGE", (time_t)hc->GetLastStateChange());
+               macros->Set("LASTHOSTSTATE", HostStateToString(GetLastState()));
+               macros->Set("LASTHOSTSTATEID", GetLastState());
+               macros->Set("LASTHOSTSTATETYPE", Service::StateTypeToString(GetLastStateType()));
+               macros->Set("LASTHOSTSTATECHANGE", (long)hc->GetLastStateChange());
 
                cr = hc->GetLastCheckResult();
        }
@@ -631,7 +622,7 @@ Dictionary::Ptr Host::CalculateDynamicMacros(void) const
                macros->Set("HOSTOUTPUT", cr->Get("output"));
                macros->Set("HOSTPERFDATA", cr->Get("performance_data_raw"));
 
-               macros->Set("LASTHOSTCHECK", (time_t)cr->Get("schedule_start"));
+               macros->Set("LASTHOSTCHECK", (long)cr->Get("schedule_start"));
        }
 
        macros->Seal();
index b9fe2ba6b6e12c68e689b6a1444b9fa493f554c7..e001ebfafe6ec3c5729c1f4f7afc261983af6407 100644 (file)
     <ClCompile Include="service-notification.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="api.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="user.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="usergroup.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="i2-icinga.h">
     <ClInclude Include="notificationrequestmessage.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="api.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="user.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="usergroup.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Headerdateien">
index 9827f3a0035d35fb6c8c4157b010b32814cf4152..f7a477104eab919911472071b8973a3e8bcdd643 100644 (file)
@@ -74,7 +74,7 @@ int IcingaApplication::Main(void)
 
        /* periodically dump the program state */
        m_RetentionTimer = boost::make_shared<Timer>();
-       m_RetentionTimer->SetInterval(300);
+       m_RetentionTimer->SetInterval(3);
        m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this));
        m_RetentionTimer->Start();
 
index 043e01981d2e642b1a73af27be1d2dd643ae54d5..1f6d405677a05113a94e2ffa45e1995d810292bc 100644 (file)
@@ -416,8 +416,6 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
        int state = cr->Get("state");
        SetState(static_cast<ServiceState>(state));
 
-       SetLastCheckResult(cr);
-
        double now = Utility::GetTime();
 
        if (old_state != GetState()) {
@@ -459,13 +457,19 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
 
        olock.Unlock();
 
+       /* Update macros - these are used by event handlers and notifications. */
+       cr->Set("macros", CalculateAllMacros());
+
+       cr->Seal();
+
+       olock.Lock();
+       SetLastCheckResult(cr);
+       olock.Unlock();
+
        /* Flush the object so other instances see the service's
         * new state when they receive the CheckResult message */
        Flush();
 
-       /* Update macros - these are used by event handlers and notifications. */
-       cr->Set("macros", CalculateAllMacros());
-
        RequestMessage rm;
        rm.SetMethod("checker::CheckResult");
 
@@ -664,8 +668,6 @@ void Service::CheckCompletedHandler(const Dictionary::Ptr& checkInfo,
                        EndpointManager::Ptr em = EndpointManager::GetInstance();
                        result->Set("current_checker", em->GetIdentity());
                }
-
-               result->Seal();
        }
 
        if (result)
index 5b7d4a68bbdffff6d8443cb713a056a5e9b72e0e..b289cf5ae84136e40b234e7183d3fac9ba65d913 100644 (file)
@@ -448,7 +448,7 @@ Dictionary::Ptr Service::CalculateDynamicMacros(void) const
                macros->Set("LASTSERVICESTATE", StateToString(GetLastState()));
                macros->Set("LASTSERVICESTATEID", GetLastState());
                macros->Set("LASTSERVICESTATETYPE", StateTypeToString(GetLastStateType()));
-               macros->Set("LASTSERVICESTATECHANGE", (time_t)GetLastStateChange());
+               macros->Set("LASTSERVICESTATECHANGE", (long)GetLastStateChange());
 
                cr = GetLastCheckResult();
        }
@@ -462,7 +462,7 @@ Dictionary::Ptr Service::CalculateDynamicMacros(void) const
                macros->Set("SERVICEOUTPUT", cr->Get("output"));
                macros->Set("SERVICEPERFDATA", cr->Get("performance_data_raw"));
 
-               macros->Set("LASTSERVICECHECK", (time_t)cr->Get("schedule_start"));
+               macros->Set("LASTSERVICECHECK", (long)cr->Get("schedule_start"));
        }
 
        macros->Seal();