mirror of https://github.com/Icinga/icinga2.git
Implemented stacktrace support for Windows.
This commit is contained in:
parent
5a166f83d7
commit
fa3f01667f
|
@ -58,6 +58,8 @@ libbase_la_SOURCES = \
|
|||
scripttask.h \
|
||||
socket.cpp \
|
||||
socket.h \
|
||||
stacktrace.cpp \
|
||||
stacktrace.h \
|
||||
stdiostream.cpp \
|
||||
stdiostream.h \
|
||||
stream.cpp \
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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" />
|
||||
|
@ -177,7 +181,7 @@
|
|||
<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>
|
||||
|
@ -196,7 +200,7 @@
|
|||
<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>
|
||||
|
@ -220,7 +224,7 @@
|
|||
<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>
|
||||
|
@ -244,7 +248,7 @@
|
|||
<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>
|
||||
|
|
|
@ -103,6 +103,12 @@
|
|||
<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">
|
||||
|
@ -210,6 +216,12 @@
|
|||
<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">
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
}
|
|
@ -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 */
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -58,6 +58,15 @@
|
|||
<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">
|
||||
|
@ -105,6 +114,15 @@
|
|||
<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">
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue