[Orxonox-commit 2744] r7449 - in code/trunk: cmake cmake/tools src src/libraries/util
landauf at orxonox.net
landauf at orxonox.net
Mon Sep 13 23:12:21 CEST 2010
Author: landauf
Date: 2010-09-13 23:12:21 +0200 (Mon, 13 Sep 2010)
New Revision: 7449
Added:
code/trunk/cmake/tools/FindDbgHelp.cmake
Modified:
code/trunk/cmake/LibraryConfig.cmake
code/trunk/cmake/PackageConfig.cmake
code/trunk/src/CMakeLists.txt
code/trunk/src/SpecialConfig.h.in
code/trunk/src/libraries/util/CMakeLists.txt
code/trunk/src/libraries/util/SignalHandler.cc
code/trunk/src/libraries/util/SignalHandler.h
Log:
added windows implementation of SignalHandler.
Modified: code/trunk/cmake/LibraryConfig.cmake
===================================================================
--- code/trunk/cmake/LibraryConfig.cmake 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/cmake/LibraryConfig.cmake 2010-09-13 21:12:21 UTC (rev 7449)
@@ -102,6 +102,7 @@
FIND_PACKAGE(POCO REQUIRED)
ENDIF()
IF(WIN32)
+ FIND_PACKAGE(DbgHelp)
FIND_PACKAGE(DirectX REQUIRED)
ENDIF()
Modified: code/trunk/cmake/PackageConfig.cmake
===================================================================
--- code/trunk/cmake/PackageConfig.cmake 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/cmake/PackageConfig.cmake 2010-09-13 21:12:21 UTC (rev 7449)
@@ -80,6 +80,7 @@
SET(ENV{ALUTDIR} ${DEP_INCLUDE_DIR}/freealut)
SET(ENV{BOOST_ROOT} ${DEP_INCLUDE_DIR}/boost)
SET(ENV{CEGUIDIR} ${DEP_INCLUDE_DIR}/cegui)
+SET(ENV{DBGHELP_DIR} ${DEP_INCLUDE_DIR}/dbghelp)
SET(ENV{DXSDK_DIR} ${DEP_INCLUDE_DIR}/directx)
SET(ENV{ENETDIR} ${DEP_INCLUDE_DIR}/enet)
SET(ENV{LUA_DIR} ${DEP_INCLUDE_DIR}/lua)
Added: code/trunk/cmake/tools/FindDbgHelp.cmake
===================================================================
--- code/trunk/cmake/tools/FindDbgHelp.cmake (rev 0)
+++ code/trunk/cmake/tools/FindDbgHelp.cmake 2010-09-13 21:12:21 UTC (rev 7449)
@@ -0,0 +1,27 @@
+INCLUDE(FindPackageHandleStandardArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(DBGHELP_INCLUDE_DIR dbghelp.h
+ PATHS $ENV{DBGHELP_DIR}
+ PATH_SUFFIXES include
+)
+FIND_LIBRARY(DBGHELP_LIBRARY dbghelp.lib
+ PATHS $ENV{DXSDK_DIR}
+ PATH_SUFFIXES lib Lib lib/x86 Lib/x86
+ NO_DEFAULT_PATH # Or else CMake 2.6.0 will find the dll in system32 on windows
+)
+FIND_LIBRARY(DBGHELP_LIBRARY dbghelp.lib # search again if the library wasn't found in the dependencies package
+ PATHS $ENV{DXSDK_DIR}
+ PATH_SUFFIXES lib Lib lib/x86 Lib/x86
+)
+
+# Handle the REQUIRED argument and set DBGHELP_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(DbgHelp DEFAULT_MSG
+ DBGHELP_LIBRARY
+ DBGHELP_INCLUDE_DIR
+)
+
+MARK_AS_ADVANCED(
+ DBGHELP_INCLUDE_DIR
+ DBGHELP_LIBRARY
+)
Property changes on: code/trunk/cmake/tools/FindDbgHelp.cmake
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: code/trunk/src/CMakeLists.txt
===================================================================
--- code/trunk/src/CMakeLists.txt 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/src/CMakeLists.txt 2010-09-13 21:12:21 UTC (rev 7449)
@@ -99,6 +99,10 @@
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/external/ceguilua/ceguilua-${CEGUI_VERSION})
ENDIF()
+IF (DBGHELP_FOUND)
+ INCLUDE_DIRECTORIES(${DBGHELP_INCLUDE_DIR})
+ENDIF()
+
################### Tolua Bind ##################
# Create directory because the tolua application doesn't work otherwise
Modified: code/trunk/src/SpecialConfig.h.in
===================================================================
--- code/trunk/src/SpecialConfig.h.in 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/src/SpecialConfig.h.in 2010-09-13 21:12:21 UTC (rev 7449)
@@ -49,6 +49,8 @@
#cmakedefine CMAKE_CONFIGURATION_TYPES ///< Using MSVC or XCode IDE
+#cmakedefine DBGHELP_FOUND ///< If DbgHelp was found on windows
+
// Handle default ConfigValues
namespace orxonox { namespace specialConfig
{
Modified: code/trunk/src/libraries/util/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/util/CMakeLists.txt 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/src/libraries/util/CMakeLists.txt 2010-09-13 21:12:21 UTC (rev 7449)
@@ -58,3 +58,7 @@
SOURCE_FILES
${UTIL_SRC_FILES}
)
+
+IF (DBGHELP_FOUND)
+ TARGET_LINK_LIBRARIES(util ${DBGHELP_LIBRARY})
+ENDIF()
Modified: code/trunk/src/libraries/util/SignalHandler.cc
===================================================================
--- code/trunk/src/libraries/util/SignalHandler.cc 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/src/libraries/util/SignalHandler.cc 2010-09-13 21:12:21 UTC (rev 7449)
@@ -43,7 +43,7 @@
SignalHandler* SignalHandler::singletonPtr_s = NULL;
}
-#ifdef ORXONOX_PLATFORM_LINUX
+#if defined(ORXONOX_PLATFORM_LINUX)
#include <wait.h>
#include <X11/Xlib.h>
@@ -123,7 +123,7 @@
// if the signalhandler has already been destroyed then don't do anything
if( SignalHandler::singletonPtr_s == 0 )
{
- COUT(0) << "received signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
+ COUT(0) << "Received signal " << sigName.c_str() << std::endl << "Can't write backtrace because SignalHandler is already destroyed" << std::endl;
exit(EXIT_FAILURE);
}
@@ -133,7 +133,7 @@
}
- COUT(0) << "received signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
+ COUT(0) << "Received signal " << sigName.c_str() << std::endl << "Try to write backtrace to file orxonox_crash.log" << std::endl;
int sigPipe[2];
if ( pipe(sigPipe) == -1 )
@@ -327,4 +327,347 @@
}
}
-#endif /* ORXONOX_PLATFORM_LINUX */
+#elif defined(ORXONOX_PLATFORM_WINDOWS) && defined(DBGHELP_FOUND)
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <dbghelp.h>
+
+namespace orxonox
+{
+ /// Constructor: Initializes the values, but doesn't register the exception handler.
+ SignalHandler::SignalHandler()
+ {
+ this->prevExceptionFilter_ = NULL;
+ }
+
+ /// Destructor: Removes the exception handler.
+ SignalHandler::~SignalHandler()
+ {
+ if (this->prevExceptionFilter_ != NULL)
+ {
+ // Remove the unhandled exception filter function
+ SetUnhandledExceptionFilter(this->prevExceptionFilter_);
+ this->prevExceptionFilter_ = NULL;
+ }
+ }
+
+ /// Registers an exception handler and initializes the filename of the crash log.
+ void SignalHandler::doCatch(const std::string&, const std::string& filename)
+ {
+ this->filename_ = filename;
+
+ // don't register twice
+ assert(this->prevExceptionFilter_ == NULL);
+
+ if (this->prevExceptionFilter_ == NULL)
+ {
+ // Install the unhandled exception filter function
+ this->prevExceptionFilter_ = SetUnhandledExceptionFilter(&SignalHandler::exceptionFilter);
+ }
+ }
+
+ /// Exception handler: Will be called by Windows if an unhandled exceptions occurs.
+ /* static */ LONG WINAPI SignalHandler::exceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
+ {
+ // avoid loops
+ static bool bExecuting = false;
+
+ if (!bExecuting)
+ {
+ bExecuting = true;
+
+
+ // if the signalhandler has already been destroyed then don't do anything
+ if (SignalHandler::singletonPtr_s == 0)
+ {
+ COUT(1) << "Catched an unhandled exception" << std::endl << "Can't write backtrace because SignalHandler is already destroyed" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ COUT(1) << "Catched an unhandled exception" << std::endl << "Try to write backtrace to orxonox_crash.log..." << std::endl;
+
+ // write the crash log
+ std::ofstream crashlog(SignalHandler::getInstance().filename_.c_str());
+
+ time_t now = time(NULL);
+
+ crashlog << "=======================================================" << std::endl;
+ crashlog << "= Time: " << std::string(ctime(&now));
+ crashlog << "=======================================================" << std::endl;
+ crashlog << std::endl;
+
+ const std::string& error = SignalHandler::getExceptionType(pExceptionInfo);
+
+ crashlog << error << std::endl;
+ crashlog << std::endl;
+
+ const std::string& callstack = SignalHandler::getStackTrace(pExceptionInfo);
+
+ crashlog << "Call stack:" << std::endl;
+ crashlog << callstack << std::endl;
+
+ crashlog.close();
+
+ // print the same information also to the console
+ COUT(1) << std::endl;
+ COUT(1) << error << std::endl;
+ COUT(1) << std::endl;
+ COUT(1) << "Call stack:" << std::endl;
+ COUT(1) << callstack << std::endl;
+
+ bExecuting = false;
+ }
+ else
+ {
+ COUT(1) << "An error occurred while writing the backtrace" << std::endl;
+ }
+
+ if (SignalHandler::getInstance().prevExceptionFilter_)
+ return SignalHandler::getInstance().prevExceptionFilter_(pExceptionInfo);
+ else
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ /// Returns the stack trace for either the current function, or, if @a pExceptionInfo is not NULL, for the given exception context.
+ /* static */ std::string SignalHandler::getStackTrace(PEXCEPTION_POINTERS pExceptionInfo)
+ {
+ // Initialise the symbol table to get function names:
+ SymInitialize(GetCurrentProcess(), 0, true);
+
+ // Store the current stack frame here:
+ STACKFRAME frame;
+ memset(&frame, 0, sizeof(STACKFRAME));
+
+ // Get processor information for the current thread:
+ CONTEXT context;
+ memset(&context, 0, sizeof(CONTEXT));
+
+ if (pExceptionInfo)
+ {
+ // get the context of the exception
+ context = *pExceptionInfo->ContextRecord;
+ }
+ else
+ {
+ context.ContextFlags = CONTEXT_FULL;
+
+ // Load the RTLCapture context function:
+ HINSTANCE kernel32 = LoadLibrary("Kernel32.dll");
+ typedef void (*RtlCaptureContextFunc) (CONTEXT* ContextRecord);
+ RtlCaptureContextFunc rtlCaptureContext = (RtlCaptureContextFunc) GetProcAddress(kernel32, "RtlCaptureContext");
+
+ // Capture the thread context
+ rtlCaptureContext(&context);
+ }
+
+ DWORD type;
+
+ // set the flags and initialize the stackframe struct
+ #ifdef _M_IX86
+ type = IMAGE_FILE_MACHINE_I386;
+
+ frame.AddrPC.Offset = context.Eip; // Current location in program
+ frame.AddrPC.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrStack.Offset = context.Esp; // Stack pointers current value
+ frame.AddrStack.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrFrame.Offset = context.Ebp; // Value of register used to access local function variables.
+ frame.AddrFrame.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ #elif _M_X64
+ type = IMAGE_FILE_MACHINE_AMD64;
+
+ frame.AddrPC.Offset = context.Rip; // Current location in program
+ frame.AddrPC.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrStack.Offset = context.Rsp; // Stack pointers current value
+ frame.AddrStack.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrFrame.Offset = context.Rsp; // Value of register used to access local function variables.
+ frame.AddrFrame.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ #elif _M_IA64
+ type = IMAGE_FILE_MACHINE_IA64;
+
+ frame.AddrPC.Offset = context.StIIP; // Current location in program
+ frame.AddrPC.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrStack.Offset = context.IntSp; // Stack pointers current value
+ frame.AddrStack.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrFrame.Offset = context.IntSp; // Value of register used to access local function variables.
+ frame.AddrFrame.Mode = AddrModeFlat; // Address mode for this pointer: flat 32 bit addressing
+ frame.AddrBStore.Offset = context.RsBSP; //
+ frame.AddrBStore.Mode = AddrModeFlat; //
+ #else
+ return
+ #endif
+
+ std::string output;
+
+ // Keep getting stack frames from windows till there are no more left:
+ for (int i = 0;
+ StackWalk
+ (
+ type , // MachineType
+ GetCurrentProcess() , // Process to get stack trace for
+ GetCurrentThread() , // Thread to get stack trace for
+ &frame , // Where to store next stack frame
+ &context , // Pointer to processor context record
+ 0 , // Routine to read process memory: use the default ReadProcessMemory
+ &SymFunctionTableAccess , // Routine to access the modules symbol table
+ &SymGetModuleBase , // Routine to access the modules base address
+ 0 // Something to do with 16-bit code. Not needed.
+ );
+ ++i
+ )
+ {
+ //------------------------------------------------------------------
+ // Declare an image help symbol structure to hold symbol info and
+ // name up to 256 chars This struct is of variable lenght though so
+ // it must be declared as a raw byte buffer.
+ //------------------------------------------------------------------
+ static char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 255];
+ memset(symbolBuffer, 0, sizeof(IMAGEHLP_SYMBOL) + 255);
+
+ // Cast it to a symbol struct:
+ IMAGEHLP_SYMBOL * symbol = (IMAGEHLP_SYMBOL*) symbolBuffer;
+
+ // Need to set the first two fields of this symbol before obtaining name info:
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL) + 255;
+ symbol->MaxNameLength = 254;
+
+ // The displacement from the beginning of the symbol is stored here: pretty useless
+ unsigned displacement = 0;
+
+ output += multi_cast<std::string>(i) + ": ";
+
+ // Get the symbol information from the address of the instruction pointer register:
+ if
+ (
+ SymGetSymFromAddr
+ (
+ GetCurrentProcess() , // Process to get symbol information for
+ frame.AddrPC.Offset , // Address to get symbol for: instruction pointer register
+ (DWORD*) &displacement , // Displacement from the beginning of the symbol: what is this for ?
+ symbol // Where to save the symbol
+ )
+ )
+ {
+ // Add the name of the function to the function list:
+ output += SignalHandler::pointerToString(frame.AddrPC.Offset) + " " + symbol->Name;
+ }
+ else
+ {
+ // Print an unknown location:
+ output += SignalHandler::pointerToString(frame.AddrPC.Offset);
+ }
+
+// output += " (" + SignalHandler::pointerToString(displacement) + ")";
+ output += "\n";
+ }
+
+ // Cleanup the symbol table:
+ SymCleanup(GetCurrentProcess());
+
+ return output;
+ }
+
+ /// Returns a description of the given exception.
+ // Based on code from Dr. Mingw by José Fonseca
+ /* static */ std::string SignalHandler::getExceptionType(PEXCEPTION_POINTERS pExceptionInfo)
+ {
+ PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
+ TCHAR szModule[MAX_PATH];
+ HMODULE hModule;
+
+ std::string output = (GetModuleFileName(NULL, szModule, MAX_PATH) ? SignalHandler::getModuleName(szModule) : "Application");
+ output += " caused ";
+
+ switch(pExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_ACCESS_VIOLATION: output += "an Access Violation"; break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: output += "an Array Bound Exceeded"; break;
+ case EXCEPTION_BREAKPOINT: output += "a Breakpoint"; break;
+ case EXCEPTION_DATATYPE_MISALIGNMENT: output += "a Datatype Misalignment"; break;
+ case EXCEPTION_FLT_DENORMAL_OPERAND: output += "a Float Denormal Operand"; break;
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO: output += "a Float Divide By Zero"; break;
+ case EXCEPTION_FLT_INEXACT_RESULT: output += "a Float Inexact Result"; break;
+ case EXCEPTION_FLT_INVALID_OPERATION: output += "a Float Invalid Operation"; break;
+ case EXCEPTION_FLT_OVERFLOW: output += "a Float Overflow"; break;
+ case EXCEPTION_FLT_STACK_CHECK: output += "a Float Stack Check"; break;
+ case EXCEPTION_FLT_UNDERFLOW: output += "a Float Underflow"; break;
+ case EXCEPTION_GUARD_PAGE: output += "a Guard Page"; break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION: output += "an Illegal Instruction"; break;
+ case EXCEPTION_IN_PAGE_ERROR: output += "an In Page Error"; break;
+ case EXCEPTION_INT_DIVIDE_BY_ZERO: output += "an Integer Divide By Zero"; break;
+ case EXCEPTION_INT_OVERFLOW: output += "an Integer Overflow"; break;
+ case EXCEPTION_INVALID_DISPOSITION: output += "an Invalid Disposition"; break;
+ case EXCEPTION_INVALID_HANDLE: output += "an Invalid Handle"; break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION: output += "a Noncontinuable Exception"; break;
+ case EXCEPTION_PRIV_INSTRUCTION: output += "a Privileged Instruction"; break;
+ case EXCEPTION_SINGLE_STEP: output += "a Single Step"; break;
+ case EXCEPTION_STACK_OVERFLOW: output += "a Stack Overflow"; break;
+ case DBG_CONTROL_C: output += "a Control+C"; break;
+ case DBG_CONTROL_BREAK: output += "a Control+Break"; break;
+ case DBG_TERMINATE_THREAD: output += "a Terminate Thread"; break;
+ case DBG_TERMINATE_PROCESS: output += "a Terminate Process"; break;
+ case RPC_S_UNKNOWN_IF: output += "an Unknown Interface"; break;
+ case RPC_S_SERVER_UNAVAILABLE: output += "a Server Unavailable"; break;
+ default: output += "an Unknown Exception (" + SignalHandler::pointerToString(pExceptionRecord->ExceptionCode) + ")"; break;
+ }
+
+ // Now print information about where the fault occured
+ output += " at location " + SignalHandler::pointerToString(pExceptionRecord->ExceptionAddress);
+ if ((hModule = (HMODULE) SignalHandler::getModuleBase((DWORD) pExceptionRecord->ExceptionAddress)) && GetModuleFileName(hModule, szModule, MAX_PATH))
+ {
+ output += " in module ";
+ output += SignalHandler::getModuleName(szModule);
+ }
+
+ // If the exception was an access violation, print out some additional information, to the error log and the debugger.
+ if(pExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && pExceptionRecord->NumberParameters >= 2)
+ {
+ output += " ";
+ output += pExceptionRecord->ExceptionInformation[0] ? "writing to" : "reading from";
+ output += " location ";
+ output += SignalHandler::pointerToString(pExceptionRecord->ExceptionInformation[1]);
+ }
+
+ return output;
+ }
+
+ /// Strips the directories from the path to the module and returns the module's name only.
+ /* static */ std::string SignalHandler::getModuleName(const std::string& path)
+ {
+ return path.substr(path.find_last_of('\\') + 1);
+ }
+
+ /// Retrieves the base address of the module that contains the specified address.
+ // Code from Dr. Mingw by José Fonseca
+ /* static */ DWORD SignalHandler::getModuleBase(DWORD dwAddress)
+ {
+ MEMORY_BASIC_INFORMATION Buffer;
+
+ return VirtualQuery((LPCVOID) dwAddress, &Buffer, sizeof(Buffer)) ? (DWORD) Buffer.AllocationBase : 0;
+ }
+
+ /// Converts a value to string, formatted as pointer.
+ template <typename T>
+ /* static */ std::string SignalHandler::pointerToString(T pointer)
+ {
+ std::ostringstream oss;
+
+ oss << std::setw(8) << std::setfill('0') << std::hex << pointer;
+
+ return std::string("0x") + oss.str();
+ }
+
+ /// Converts a pointer to string.
+ template <typename T>
+ /* static */ std::string SignalHandler::pointerToString(T* pointer)
+ {
+ std::ostringstream oss;
+
+ oss << pointer;
+
+ return oss.str();
+ }
+}
+
+#endif
Modified: code/trunk/src/libraries/util/SignalHandler.h
===================================================================
--- code/trunk/src/libraries/util/SignalHandler.h 2010-09-13 13:14:52 UTC (rev 7448)
+++ code/trunk/src/libraries/util/SignalHandler.h 2010-09-13 21:12:21 UTC (rev 7449)
@@ -38,16 +38,18 @@
#include "UtilPrereqs.h"
#include <cassert>
-#include <list>
#include <string>
#include "Singleton.h"
+#include "SpecialConfig.h"
namespace orxonox
{
typedef int (*SignalCallback)( void * someData );
}
-#ifdef ORXONOX_PLATFORM_LINUX
+#if defined(ORXONOX_PLATFORM_LINUX)
+
+#include <list>
#include <signal.h>
namespace orxonox
@@ -96,26 +98,58 @@
};
}
-#else /* ORXONOX_PLATFORM_LINUX */
+#elif defined(ORXONOX_PLATFORM_WINDOWS) && defined(DBGHELP_FOUND)
+#include <windows.h>
+
namespace orxonox
{
- /// The SignalHandler is used to catch signals like SIGSEGV and write a backtrace to the logfile. Not implemented on Windows.
+ /// The SignalHandler is used to catch unhandled exceptions like access violations and write a backtrace to the logfile.
class _UtilExport SignalHandler : public Singleton<SignalHandler>
{
friend class Singleton<SignalHandler>;
public:
- SignalHandler() { }
- ~SignalHandler() { }
+ SignalHandler();
+ ~SignalHandler();
+
+ void doCatch( const std::string & appName, const std::string & filename );
+
+ private:
+ static LONG WINAPI exceptionFilter(PEXCEPTION_POINTERS pExceptionInfo);
+
+ static std::string getStackTrace(PEXCEPTION_POINTERS pExceptionInfo = NULL);
+ static std::string getExceptionType(PEXCEPTION_POINTERS pExceptionInfo);
+ static std::string getModuleName(const std::string& path);
+ static DWORD getModuleBase(DWORD dwAddress);
+
+ template <typename T>
+ static std::string pointerToString(T pointer);
+ template <typename T>
+ static std::string pointerToString(T* pointer);
+
+ static SignalHandler* singletonPtr_s;
+
+ std::string filename_;
+ LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter_;
+ };
+}
+
+#else
+
+namespace orxonox
+{
+ /// The SignalHandler is used to catch signals like SIGSEGV and write a backtrace to the logfile. Not implemented on systems except Linux and Windows.
+ class _UtilExport SignalHandler : public Singleton<SignalHandler>
+ {
+ friend class Singleton<SignalHandler>;
+ public:
void doCatch( const std::string & appName, const std::string & filename ) {}
- void dontCatch() {}
- void registerCallback( SignalCallback cb, void * someData ) {}
private:
static SignalHandler* singletonPtr_s;
};
}
-#endif /* ORXONOX_PLATFORM_LINUX */
+#endif
#endif /* _SignalHandler_H__ */
More information about the Orxonox-commit
mailing list