Skip to content

Commit

Permalink
<WIP>
Browse files Browse the repository at this point in the history
  • Loading branch information
dscharrer committed Jan 7, 2012
1 parent d43db2c commit 559b93f
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 107 deletions.
11 changes: 8 additions & 3 deletions CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 0 additions & 6 deletions src/core/Core.cpp
Expand Up @@ -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();

Expand Down
71 changes: 26 additions & 45 deletions src/platform/CrashHandler.cpp
Expand Up @@ -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 <execinfo.h>
#endif
Expand Down Expand Up @@ -126,64 +129,52 @@ 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;
gCrashHandlerImpl = 0;
return false;
}
}

gInitCount++;
return true;
}

void CrashHandler::shutdown() {
gInitCount--;

if(gInitCount == 0) {
delete gCrashHandlerImpl;
gCrashHandlerImpl = 0;
Expand Down Expand Up @@ -235,13 +226,3 @@ void CrashHandler::unregisterCrashCallback(CrashCallback crashCallback) {

gCrashHandlerImpl->unregisterCrashCallback(crashCallback);
}

#else

void initCrashHandler() {

// TODO implement for this platform

}

#endif
11 changes: 4 additions & 7 deletions src/platform/CrashHandler.h
Expand Up @@ -21,13 +21,11 @@
#define ARX_PLATFORM_CRASHHANDLER_H

#include <string>
#include "platform/Platform.h"

#if ARX_PLATFORM != ARX_PLATFORM_WIN32
#include <sstream>

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.
Expand Down Expand Up @@ -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
5 changes: 3 additions & 2 deletions src/platform/Thread.cpp
Expand Up @@ -19,6 +19,9 @@

#include "platform/Thread.h"

#include "platform/CrashHandler.h"
#include "platform/Platform.h"

#if defined(HAVE_PTHREADS)

#include <sched.h>
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/platform/Thread.h
Expand Up @@ -22,6 +22,8 @@

#include "Configure.h"

#include <string>

#if defined(HAVE_PTHREADS)
#include <pthread.h>
#elif defined(HAVE_WINAPI)
Expand Down Expand Up @@ -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);

Expand Down
Expand Up @@ -17,11 +17,11 @@
* along with Arx Libertatis. If not, see <http://www.gnu.org/licenses/>.
*/

#include "CrashHandlerLinux.h"
#include "CrashHandlerPOSIX.h"

#include <float.h>
#include <signal.h>
#include <string.h>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>

Expand All @@ -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
Expand All @@ -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

Expand All @@ -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 {
Expand All @@ -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<CrashHandler::CrashCallback>::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;
Expand Down Expand Up @@ -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);
}


Expand All @@ -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);
}
CrashHandlerPOSIX::getInstance().handleCrash(SIGNAL_SIGFPE, FPECode);
}

0 comments on commit 559b93f

Please sign in to comment.