diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b8fcb6d20..c8c477022d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -512,7 +512,7 @@ set(PLATFORM_SOURCES src/platform/Time.cpp src/platform/crashhandler/CrashHandlerImpl.cpp ) - +set(PLATFORM_CRASHHANDLER_POSIX_SOURCES src/platform/crashhandler/CrashHandlerPOSIX.cpp) set(PLATFORM_CRASHHANDLER_WINDOWS_SOURCES src/platform/crashhandler/CrashHandlerWindows.cpp) set(SCENE_SOURCES @@ -641,8 +641,13 @@ else() endif() list(APPEND IO_SOURCES ${IO_FILESYSTEM_SOURCES}) -#TODO - select the right crash handler for the platform -list(APPEND PLATFORM_SOURCES ${PLATFORM_CRASHHANDLER_WINDOWS_SOURCES}) +if(HAVE_SIGNAL AND HAVE_EXECLP) + list(APPEND PLATFORM_SOURCES ${PLATFORM_CRASHHANDLER_POSIX_SOURCES}) + set(HAVE_CRASHHANDLER_POSIX 1) +elseif(HAVE_WINAPI) + list(APPEND PLATFORM_SOURCES ${PLATFORM_CRASHHANDLER_WINDOWS_SOURCES}) + set(HAVE_CRASHHANDLER_WINDOWS 1) +endif() if(NOT MSVC) check_link_library(Boost Boost_LIBRARIES) diff --git a/src/core/Core.cpp b/src/core/Core.cpp index 3bc1015ae1..be0eadd3ea 100644 --- a/src/core/Core.cpp +++ b/src/core/Core.cpp @@ -629,13 +629,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, ARX_UNUSED(nCmdShow); #endif // #if ARX_PLATFORM != ARX_PLATFORM_WIN32 - -#if ARX_PLATFORM != ARX_PLATFORM_WIN32 - initCrashHandler(); -#else CrashHandler::initialize(); -#endif - Logger::init(); diff --git a/src/platform/CrashHandler.cpp b/src/platform/CrashHandler.cpp index 7383ade7ac..f311503b3c 100644 --- a/src/platform/CrashHandler.cpp +++ b/src/platform/CrashHandler.cpp @@ -27,11 +27,14 @@ #include "platform/Platform.h" #include "Configure.h" +/* #if defined(HAVE_FORK) && defined(HAVE_READLINK) && defined(HAVE_KILL) \ && defined(HAVE_SIGNAL) && defined(SIGKILL) \ && (defined(HAVE_EXECLP) || (defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD))) \ && (defined(SIGSEGV) || defined(SIGILL) || defined(SIGFPE)) + + #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD) #include #endif @@ -126,49 +129,38 @@ static void crashHandler(int signal_) { } -void initCrashHandler() { - - // Catch 'bad' signals so we can print some debug output. - -#ifdef SIGSEGV - signal(SIGSEGV, crashHandler); -#endif - -#ifdef SIGILL - signal(SIGILL, crashHandler); -#endif - -#ifdef SIGFPE - signal(SIGFPE, crashHandler); -#endif - -#ifdef SIGABRT - signal(SIGABRT, crashHandler); -#endif - -} - // don't have enough POSIX functionality for backtraces #elif 0 // TODO ARX_PLATFORM == ARX_PLATFORM_WIN32 +*/ - - - - +#if defined(HAVE_CRASHHANDLER_POSIX) +#include "platform/crashhandler/CrashHandlerPOSIX.h" +#elif defined(HAVE_CRASHHANDLER_WINDOWS) #include "platform/crashhandler/CrashHandlerWindows.h" +#endif -static CrashHandlerImpl* gCrashHandlerImpl = 0; +static CrashHandlerImpl * gCrashHandlerImpl = 0; static int gInitCount = 0; bool CrashHandler::initialize() { - if(IsDebuggerPresent()) { - LogInfo << "Debugger attached, disabling crash handler."; - return false; - } - + if(!gCrashHandlerImpl){ + +#if defined(HAVE_CRASHHANDLER_POSIX) + + gCrashHandlerImpl = new CrashHandlerPOSIX(); + +#elif defined(HAVE_CRASHHANDLER_WINDOWS) + + if(IsDebuggerPresent()) { + LogInfo << "Debugger attached, disabling crash handler."; + return false; + } + gCrashHandlerImpl = new CrashHandlerWindows(); - + +#endif + bool initialized = gCrashHandlerImpl->initialize(); if(!initialized) { delete gCrashHandlerImpl; @@ -176,14 +168,13 @@ bool CrashHandler::initialize() { return false; } } - + gInitCount++; return true; } void CrashHandler::shutdown() { gInitCount--; - if(gInitCount == 0) { delete gCrashHandlerImpl; gCrashHandlerImpl = 0; @@ -235,13 +226,3 @@ void CrashHandler::unregisterCrashCallback(CrashCallback crashCallback) { gCrashHandlerImpl->unregisterCrashCallback(crashCallback); } - -#else - -void initCrashHandler() { - - // TODO implement for this platform - -} - -#endif diff --git a/src/platform/CrashHandler.h b/src/platform/CrashHandler.h index b84c131737..cb985f1705 100644 --- a/src/platform/CrashHandler.h +++ b/src/platform/CrashHandler.h @@ -21,13 +21,11 @@ #define ARX_PLATFORM_CRASHHANDLER_H #include -#include "platform/Platform.h" - -#if ARX_PLATFORM != ARX_PLATFORM_WIN32 +#include -void initCrashHandler(); +#include "platform/Platform.h" -#elif 0 // TODO +namespace fs { class path; } /** * Handle crashes and collect as much info as possible in order to ease bug fixing. @@ -136,8 +134,7 @@ class CrashHandler { * defect which is not a crash. */ static void handleCrash(int crashType, void* crashExtraInfo = 0, int fpeCode = 0); + }; -#endif // #if ARX_PLATFORM != ARX_PLATFORM_WIN32 - #endif // ARX_PLATFORM_CRASHHANDLER_H diff --git a/src/platform/Thread.cpp b/src/platform/Thread.cpp index 8665886f8d..3928dcf4d8 100644 --- a/src/platform/Thread.cpp +++ b/src/platform/Thread.cpp @@ -19,6 +19,9 @@ #include "platform/Thread.h" +#include "platform/CrashHandler.h" +#include "platform/Platform.h" + #if defined(HAVE_PTHREADS) #include @@ -88,8 +91,6 @@ void Thread::exit() { #elif defined(HAVE_WINAPI) -#include "platform/Platform.h" - Thread::Thread() { thread = CreateThread(NULL, 0, entryPoint, this, CREATE_SUSPENDED, NULL); arx_assert(thread); diff --git a/src/platform/Thread.h b/src/platform/Thread.h index ab6c1f1325..8096e572a6 100644 --- a/src/platform/Thread.h +++ b/src/platform/Thread.h @@ -22,6 +22,8 @@ #include "Configure.h" +#include + #if defined(HAVE_PTHREADS) #include #elif defined(HAVE_WINAPI) @@ -75,7 +77,7 @@ class Thread { * \note This should be called BEFORE starting the thread. * \param threadName The thread name. */ - void setThreadName(const std::string& threadName); + void setThreadName(const std::string & threadName); void setPriority(Priority priority); diff --git a/src/platform/crashhandler/CrashHandlerLinux.cpp b/src/platform/crashhandler/CrashHandlerPOSIX.cpp similarity index 87% rename from src/platform/crashhandler/CrashHandlerLinux.cpp rename to src/platform/crashhandler/CrashHandlerPOSIX.cpp index cfa94ad85c..c473720257 100644 --- a/src/platform/crashhandler/CrashHandlerLinux.cpp +++ b/src/platform/crashhandler/CrashHandlerPOSIX.cpp @@ -17,11 +17,11 @@ * along with Arx Libertatis. If not, see . */ -#include "CrashHandlerLinux.h" +#include "CrashHandlerPOSIX.h" #include #include -#include +#include #include #include @@ -36,27 +36,28 @@ struct PlatformCrashHandlers { void SignalHandler(int signalCode); -CrashHandlerLinux* CrashHandlerLinux::m_sInstance = 0; +CrashHandlerPOSIX* CrashHandlerPOSIX::m_sInstance = 0; -CrashHandlerLinux::CrashHandlerLinux() { +CrashHandlerPOSIX::CrashHandlerPOSIX() { m_sInstance = this; } -CrashHandlerLinux::~CrashHandlerLinux() { +CrashHandlerPOSIX::~CrashHandlerPOSIX() { m_sInstance = 0; } -CrashHandlerLinux& CrashHandlerLinux::getInstance() { +CrashHandlerPOSIX& CrashHandlerPOSIX::getInstance() { arx_assert(m_sInstance != 0); return *m_sInstance; } -bool CrashHandlerLinux::registerCrashHandlers() { +bool CrashHandlerPOSIX::registerCrashHandlers() { + arx_assert(m_pPreviousCrashHandlers == 0); m_pPreviousCrashHandlers = new PlatformCrashHandlers; - + // Catch 'bad' signals so we can print some debug output. - + #ifdef SIGSEGV m_pPreviousCrashHandlers->m_SIGSEGVHandler = signal(SIGSEGV, SignalHandler); #endif @@ -72,15 +73,16 @@ bool CrashHandlerLinux::registerCrashHandlers() { #ifdef SIGABRT m_pPreviousCrashHandlers->m_SIGABRTHandler = signal(SIGABRT, SignalHandler); #endif - + // We must also register the main thread crash handlers. return registerThreadCrashHandlers(); } -void CrashHandlerLinux::unregisterCrashHandlers() { +void CrashHandlerPOSIX::unregisterCrashHandlers() { + unregisterThreadCrashHandlers(); - - #ifdef SIGSEGV + +#ifdef SIGSEGV signal(SIGSEGV, m_pPreviousCrashHandlers->m_SIGSEGVHandler); #endif @@ -95,18 +97,19 @@ void CrashHandlerLinux::unregisterCrashHandlers() { #ifdef SIGABRT signal(SIGABRT, m_pPreviousCrashHandlers->m_SIGABRTHandler); #endif - + delete m_pPreviousCrashHandlers; m_pPreviousCrashHandlers = 0; } -bool CrashHandlerLinux::registerThreadCrashHandlers() { +bool CrashHandlerPOSIX::registerThreadCrashHandlers() { // All POSIX signals are process wide, so no thread specific actions are needed return true; } -void CrashHandlerLinux::unregisterThreadCrashHandlers() { +void CrashHandlerPOSIX::unregisterThreadCrashHandlers() { + // All POSIX signals are process wide, so no thread specific actions are needed } enum CrashType { @@ -117,16 +120,17 @@ enum CrashType { SIGNAL_UNKNOWN }; -void CrashHandlerLinux::handleCrash(int crashType, int FPECode) { +void CrashHandlerPOSIX::handleCrash(int crashType, int FPECode) { + Autolock autoLock(&m_Lock); - + // Run the callbacks for(std::vector::iterator it = m_crashCallbacks.begin(); it != m_crashCallbacks.end(); ++it) { (*it)(); } - + const char* crashSummary; - + switch(crashType) { case SIGNAL_SIGABRT: crashSummary = "Abnormal termination"; break; case SIGNAL_SIGFPE: crashSummary = "Floating-point error"; break; @@ -158,23 +162,23 @@ void CrashHandlerLinux::handleCrash(int crashType, int FPECode) { } } strcat(m_pCrashInfo->detailedCrashInfo, "\n\n"); - + // Get current thread id m_pCrashInfo->threadId = boost::interprocess::detail::get_current_thread_id(); - + strcpy(m_pCrashInfo->crashReportFolder, "Crashes"); char arguments[256]; strcpy(arguments, "-crashinfo="); strcat(arguments, m_SharedMemoryName.c_str()); bool bCreateProcess = start_the_process_here("CrashReporter/arxcrashreporterforlinux.exe", arguments); - + // If CrashReporter was started, wait for its signal before exiting. if(bCreateProcess) { m_pCrashInfo->exitLock.wait(); } - now_lets_brutally_terminate_this_doomed_process(); + exit(1); } @@ -187,10 +191,9 @@ void SignalHandler(int signalCode) { case SIGFPE: crashType = SIGNAL_SIGFPE; break; default: crashType = SIGNAL_UNKNOWN; break; } - - CrashHandlerLinux::getInstance().handleCrash(crashType); + CrashHandlerPOSIX::getInstance().handleCrash(crashType); } void SIGFPEHandler(int code, int FPECode) { - CrashHandlerLinux::getInstance().handleCrash(SIGNAL_SIGFPE, FPECode); -} \ No newline at end of file + CrashHandlerPOSIX::getInstance().handleCrash(SIGNAL_SIGFPE, FPECode); +} diff --git a/src/platform/crashhandler/CrashHandlerLinux.h b/src/platform/crashhandler/CrashHandlerPOSIX.h similarity index 83% rename from src/platform/crashhandler/CrashHandlerLinux.h rename to src/platform/crashhandler/CrashHandlerPOSIX.h index e4cc1fa47e..44d003cd21 100644 --- a/src/platform/crashhandler/CrashHandlerLinux.h +++ b/src/platform/crashhandler/CrashHandlerPOSIX.h @@ -22,32 +22,35 @@ #include "platform/crashhandler/CrashHandlerImpl.h" -class CrashHandlerLinux : public CrashHandlerImpl { +class CrashHandlerPOSIX : public CrashHandlerImpl { + public: - CrashHandlerLinux(); - virtual ~CrashHandlerLinux(); - + + CrashHandlerPOSIX(); + virtual ~CrashHandlerPOSIX(); + bool initialize(); - + bool registerThreadCrashHandlers(); void unregisterThreadCrashHandlers(); - + void registerCrashCallback(CrashHandler::CrashCallback crashCallback); void unregisterCrashCallback(CrashHandler::CrashCallback crashCallback); - + void handleCrash(int crashType, int fpeCode = 0); - - static CrashHandlerWindows& getInstance(); - + + static CrashHandlerPOSIX & getInstance(); + private: + bool registerCrashHandlers(); void unregisterCrashHandlers(); -private: // Crash handlers to restore. - struct PlatformCrashHandlers* m_pPreviousCrashHandlers; - - static CrashHandlerLinux* m_sInstance; + struct PlatformCrashHandlers * m_pPreviousCrashHandlers; + + static CrashHandlerPOSIX * m_sInstance; + }; #endif // ARX_PLATFORM_CRASHHANDLER_CRASHHANDLERLINUX_H diff --git a/src/platform/crashhandler/CrashInfo.h b/src/platform/crashhandler/CrashInfo.h index b9eec9dbea..6982eba2fa 100644 --- a/src/platform/crashhandler/CrashInfo.h +++ b/src/platform/crashhandler/CrashInfo.h @@ -72,7 +72,7 @@ struct CrashInfoBase { #if ARX_PLATFORM == ARX_PLATFORM_LINUX struct CrashInfo : public CrashInfoBase { -} +}; #elif ARX_PLATFORM == ARX_PLATFORM_WIN32