From 46761ee07df6a87ab9e4b34e837a77f9736e33f2 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 5 Jul 2015 12:59:58 -0700 Subject: [PATCH 1/5] Make hsAssert useful on Linux --- Sources/Plasma/CoreLib/HeadSpin.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Sources/Plasma/CoreLib/HeadSpin.cpp b/Sources/Plasma/CoreLib/HeadSpin.cpp index a9919dea..ecac79fb 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.cpp +++ b/Sources/Plasma/CoreLib/HeadSpin.cpp @@ -118,17 +118,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)) + if (_CrtDbgReport(_CRT_ASSERT, file, line, NULL, msg)) DebugBreak(); } 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); + abort(); } +#endif // HS_DEBUGGING #else DebugBreakIfDebuggerPresent(); #endif // defined(HS_DEBUGGING) || !defined(PLASMA_EXTERNAL_RELEASE) @@ -164,13 +167,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); } } From db7bf2b3b7012cafee486c06e7fb905f3c08eed3 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sat, 6 Jun 2015 18:04:20 -0700 Subject: [PATCH 2/5] Added Linux check for debugger presence. --- CMakeLists.txt | 7 +++++++ Sources/Plasma/CoreLib/HeadSpin.cpp | 28 +++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) 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 ecac79fb..2be9e794 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.cpp +++ b/Sources/Plasma/CoreLib/HeadSpin.cpp @@ -46,6 +46,13 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #ifdef _MSC_VER # include #endif + +#if defined(HS_DEBUGGING) && defined(HS_BUILD_FOR_LINUX) +# include +# include +# include +# include +#endif #pragma hdrstop #include "hsTemplates.h" @@ -139,8 +146,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; From 96bc3a1c7ec1dd39c4c96097444e57effbb8c706 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 5 Jul 2015 13:18:25 -0700 Subject: [PATCH 3/5] Also trigger the debugger from Unix if possible --- Sources/Plasma/CoreLib/HeadSpin.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Sources/Plasma/CoreLib/HeadSpin.cpp b/Sources/Plasma/CoreLib/HeadSpin.cpp index 2be9e794..530d7eb7 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.cpp +++ b/Sources/Plasma/CoreLib/HeadSpin.cpp @@ -53,6 +53,11 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com # include # include #endif + +#if defined(HS_BUILD_FOR_UNIX) +# include +#endif + #pragma hdrstop #include "hsTemplates.h" @@ -136,6 +141,9 @@ void ErrorAssert(int line, const char* file, const char* fmt, ...) { char str[] = "-------\nASSERTION FAILED:\nFile: %s Line: %i\nMessage: %s\n-------"; DebugMsg(str, file, line, msg); + DebugBreakIfDebuggerPresent(); + + // In case the debug trap is ignored abort(); } #endif // HS_DEBUGGING @@ -175,7 +183,7 @@ bool DebugIsDebuggerPresent() void DebugBreakIfDebuggerPresent() { -#ifdef _MSC_VER +#if defined(_MSC_VER) __try { __debugbreak(); @@ -183,6 +191,8 @@ void DebugBreakIfDebuggerPresent() // Debugger not present or some such shwiz. // Whatever. Don't crash here. } +#elif defined(HS_BUILD_FOR_UNIX) + raise(SIGTRAP); #endif // _MSC_VER } From 68e2dba4392bc652faa5afc86da1917fd95d851a Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 5 Jul 2015 13:22:39 -0700 Subject: [PATCH 4/5] Shuffle headers a bit --- Sources/Plasma/CoreLib/HeadSpin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Plasma/CoreLib/HeadSpin.cpp b/Sources/Plasma/CoreLib/HeadSpin.cpp index 530d7eb7..5dc94413 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.cpp +++ b/Sources/Plasma/CoreLib/HeadSpin.cpp @@ -47,7 +47,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com # include #endif -#if defined(HS_DEBUGGING) && defined(HS_BUILD_FOR_LINUX) +#pragma hdrstop + +#if defined(HS_DEBUGGING) && defined(HS_BUILD_FOR_UNIX) # include # include # include @@ -58,8 +60,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com # include #endif -#pragma hdrstop - #include "hsTemplates.h" #include "plFormat.h" From 6ad2f7ae2428e5fe4101eaec6c48de497cc04c50 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 5 Jul 2015 16:11:30 -0700 Subject: [PATCH 5/5] Fix ErrorAssert handling to allow bypassing the assert if we're attached to a debugger --- Sources/Plasma/CoreLib/HeadSpin.cpp | 22 +++++++++++++++++----- Sources/Plasma/CoreLib/HeadSpin.h | 5 +++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Sources/Plasma/CoreLib/HeadSpin.cpp b/Sources/Plasma/CoreLib/HeadSpin.cpp index 5dc94413..bbb46fb6 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.cpp +++ b/Sources/Plasma/CoreLib/HeadSpin.cpp @@ -135,16 +135,13 @@ void ErrorAssert(int line, const char* file, const char* fmt, ...) if (s_GuiAsserts) { if (_CrtDbgReport(_CRT_ASSERT, file, line, NULL, msg)) - DebugBreak(); + DebugBreakAlways(); } else #endif // _MSC_VER { char str[] = "-------\nASSERTION FAILED:\nFile: %s Line: %i\nMessage: %s\n-------"; DebugMsg(str, file, line, msg); - DebugBreakIfDebuggerPresent(); - - // In case the debug trap is ignored - abort(); + DebugBreakAlways(); } #endif // HS_DEBUGGING #else @@ -191,8 +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 } 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