diff --git a/CMakeLists.txt b/CMakeLists.txt index e0d9d164..e38406e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,12 +22,19 @@ include(cmake/CompilerChecks.cmake) if(WIN32 AND NOT CYGWIN) add_definitions(-DHS_BUILD_FOR_WIN32) endif(WIN32 AND NOT CYGWIN) + if(UNIX) + # This is set for both Linux and Mac builds add_definitions(-DHS_BUILD_FOR_UNIX) endif(UNIX) + if(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_definitions(-DHS_BUILD_FOR_OSX) endif(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + add_definitions(-DHS_BUILD_FOR_LINUX) +endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # End HeadSpin Configuration set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") diff --git a/Sources/Plasma/CoreLib/HeadSpin.cpp b/Sources/Plasma/CoreLib/HeadSpin.cpp index a9919dea..bbb46fb6 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.cpp +++ b/Sources/Plasma/CoreLib/HeadSpin.cpp @@ -46,8 +46,20 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #ifdef _MSC_VER # include #endif + #pragma hdrstop +#if defined(HS_DEBUGGING) && defined(HS_BUILD_FOR_UNIX) +# include +# include +# include +# include +#endif + +#if defined(HS_BUILD_FOR_UNIX) +# include +#endif + #include "hsTemplates.h" #include "plFormat.h" @@ -118,17 +130,20 @@ void ErrorAssert(int line, const char* file, const char* fmt, ...) va_list args; va_start(args, fmt); vsnprintf(msg, arrsize(msg), fmt, args); -#if defined(HS_DEBUGGING) && defined(_MSC_VER) +#if defined(HS_DEBUGGING) +#if defined(_MSC_VER) if (s_GuiAsserts) { - if(_CrtDbgReport(_CRT_ASSERT, file, line, NULL, msg)) - DebugBreak(); + if (_CrtDbgReport(_CRT_ASSERT, file, line, NULL, msg)) + DebugBreakAlways(); } else -#endif // HS_DEBUGGING - if (DebugIsDebuggerPresent()) { +#endif // _MSC_VER + { char str[] = "-------\nASSERTION FAILED:\nFile: %s Line: %i\nMessage: %s\n-------"; DebugMsg(str, file, line, msg); + DebugBreakAlways(); } +#endif // HS_DEBUGGING #else DebugBreakIfDebuggerPresent(); #endif // defined(HS_DEBUGGING) || !defined(PLASMA_EXTERNAL_RELEASE) @@ -136,8 +151,27 @@ void ErrorAssert(int line, const char* file, const char* fmt, ...) bool DebugIsDebuggerPresent() { -#ifdef _MSC_VER +#if defined(HS_BUILD_FOR_WIN32) return IsDebuggerPresent(); +#elif defined(HS_BUILD_FOR_LINUX) + // From http://google-perftools.googlecode.com/svn/trunk/src/heap-checker.cc + char buf[256]; // TracerPid comes relatively earlier in status output + int fd = open("/proc/self/status", O_RDONLY); + if (fd == -1) { + return false; // Can't tell for sure. + } + const int len = read(fd, buf, sizeof(buf)); + bool rc = false; + if (len > 0) { + const char* const kTracerPid = "TracerPid:\t"; + buf[len - 1] = '\0'; + const char* p = strstr(buf, kTracerPid); + if (p) { + rc = (strncmp(p + strlen(kTracerPid), "0\n", 2) != 0); + } + } + close(fd); + return rc; #else // FIXME return false; @@ -146,7 +180,7 @@ bool DebugIsDebuggerPresent() void DebugBreakIfDebuggerPresent() { -#ifdef _MSC_VER +#if defined(_MSC_VER) __try { __debugbreak(); @@ -154,6 +188,23 @@ void DebugBreakIfDebuggerPresent() // Debugger not present or some such shwiz. // Whatever. Don't crash here. } +#elif defined(HS_BUILD_FOR_UNIX) + if (DebugIsDebuggerPresent()) + raise(SIGTRAP); +#else + // FIXME +#endif // _MSC_VER +} + +void DebugBreakAlways() +{ +#if defined(_MSC_VER) + DebugBreak(); +#elif defined(HS_BUILD_FOR_UNIX) + raise(SIGTRAP); +#else + // FIXME + abort(); #endif // _MSC_VER } @@ -164,13 +215,14 @@ void DebugMsg(const char* fmt, ...) va_start(args, fmt); vsnprintf(msg, arrsize(msg), fmt, args); +#ifdef _MSC_VER if (DebugIsDebuggerPresent()) { -#ifdef _MSC_VER OutputDebugStringA(msg); OutputDebugStringA("\n"); + } else #endif - } else { + { fprintf(stderr, "%s\n", msg); } } diff --git a/Sources/Plasma/CoreLib/HeadSpin.h b/Sources/Plasma/CoreLib/HeadSpin.h index 9a4d567a..5ec7725a 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.h +++ b/Sources/Plasma/CoreLib/HeadSpin.h @@ -374,8 +374,9 @@ hsDebugMessageProc hsSetStatusMessageProc(hsDebugMessageProc newProc); void ErrorEnableGui (bool enabled); void ErrorAssert (int line, const char* file, const char* fmt, ...); -bool DebugIsDebuggerPresent (); -void DebugBreakIfDebuggerPresent (); +bool DebugIsDebuggerPresent(); +void DebugBreakIfDebuggerPresent(); +void DebugBreakAlways(); void DebugMsg(const char* fmt, ...); #ifdef HS_DEBUGGING