From 1cf76c1ee83e0c29d0e377c0c278e4f289afd7ac Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Mon, 26 Feb 2018 12:04:09 -0600 Subject: [PATCH 1/6] macosx does not recognize pipe-related values if they were initialized after UnixSignal functions. --- core/unix/src/TUnixSignalManager.cxx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/unix/src/TUnixSignalManager.cxx b/core/unix/src/TUnixSignalManager.cxx index 3084755e9e253..4e2a0876e9355 100644 --- a/core/unix/src/TUnixSignalManager.cxx +++ b/core/unix/src/TUnixSignalManager.cxx @@ -272,6 +272,12 @@ void TUnixSignalManager::Init() fSignals = new TFdSet; + //--- initialize pipe-related data structer here, macosx does not recognize their values if they were inialized after UnixSignal functions + gStackTraceHelper.fParentToChild[0] = -1; + gStackTraceHelper.fParentToChild[1] = -1; + gStackTraceHelper.fChildToParent[0] = -1; + gStackTraceHelper.fChildToParent[1] = -1; + //--- install default handlers UnixSignal(kSigChild, SigHandler); UnixSignal(kSigBus, SigHandler); @@ -301,11 +307,6 @@ void TUnixSignalManager::Init() } #endif - gStackTraceHelper.fParentToChild[0] = -1; - gStackTraceHelper.fParentToChild[1] = -1; - gStackTraceHelper.fChildToParent[0] = -1; - gStackTraceHelper.fChildToParent[1] = -1; - StackTraceHelperInit(); } From ac9e6cc031076ae4ca2bb208c9e67791f48cd0a4 Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Mon, 26 Feb 2018 12:21:22 -0600 Subject: [PATCH 2/6] Keep macosx call StackTrace function. --- core/unix/src/TUnixSignalManager.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/unix/src/TUnixSignalManager.cxx b/core/unix/src/TUnixSignalManager.cxx index 4e2a0876e9355..c7d1230fc53f1 100644 --- a/core/unix/src/TUnixSignalManager.cxx +++ b/core/unix/src/TUnixSignalManager.cxx @@ -307,7 +307,9 @@ void TUnixSignalManager::Init() } #endif +#ifdef R__LINUX StackTraceHelperInit(); +#endif } //////////////////////////////////////////////////////////////////////////////// @@ -528,7 +530,11 @@ void TUnixSignalManager::DispatchSignals(ESignals sig) if ((sig == kSigIllegalInstruction) || (sig == kSigSegmentationViolation) || (sig == kSigBus) || (sig == kSigFloatingException)) { +#if defined(R__LINUX) StackTraceTriggerThread(); +#elif defined(R__MACOSX) + StackTrace(); +#endif signal(sig, SIG_DFL); raise(sig); if (gApplication) From d8fce1ec6190e4a16d1b184ff87b1055010192e8 Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Thu, 5 Apr 2018 15:11:55 -0500 Subject: [PATCH 3/6] Reverted MacOSX stacktrace to Linux implementation. --- core/unix/src/TUnixSignalManager.cxx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/unix/src/TUnixSignalManager.cxx b/core/unix/src/TUnixSignalManager.cxx index c7d1230fc53f1..4e2a0876e9355 100644 --- a/core/unix/src/TUnixSignalManager.cxx +++ b/core/unix/src/TUnixSignalManager.cxx @@ -307,9 +307,7 @@ void TUnixSignalManager::Init() } #endif -#ifdef R__LINUX StackTraceHelperInit(); -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -530,11 +528,7 @@ void TUnixSignalManager::DispatchSignals(ESignals sig) if ((sig == kSigIllegalInstruction) || (sig == kSigSegmentationViolation) || (sig == kSigBus) || (sig == kSigFloatingException)) { -#if defined(R__LINUX) StackTraceTriggerThread(); -#elif defined(R__MACOSX) - StackTrace(); -#endif signal(sig, SIG_DFL); raise(sig); if (gApplication) From ec8e186c61645c18120a028f7ad7605182528144 Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Thu, 5 Apr 2018 15:15:42 -0500 Subject: [PATCH 4/6] Add lldb-backtrace script for MacOSX. --- core/unix/src/TUnixSignalManager.cxx | 8 ++++++ etc/lldb-backtrace.sh | 41 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100755 etc/lldb-backtrace.sh diff --git a/core/unix/src/TUnixSignalManager.cxx b/core/unix/src/TUnixSignalManager.cxx index 4e2a0876e9355..82057469af1f8 100644 --- a/core/unix/src/TUnixSignalManager.cxx +++ b/core/unix/src/TUnixSignalManager.cxx @@ -296,12 +296,20 @@ void TUnixSignalManager::Init() } #ifdef ROOTETCDIR +#if defined(R__MACOSX) + if(snprintf(gStackTraceHelper.fPidString, kStringLength-1, "%s/lldb-backtrace.sh", ROOTETCDIR) >= kStringLength) { +#else if(snprintf(gStackTraceHelper.fPidString, kStringLength-1, "%s/gdb-backtrace.sh", ROOTETCDIR) >= kStringLength) { +#endif SignalSafeErrWrite("Unable to pre-allocate executable information"); return; } +#else +#if defined(R__MACOSX) + if(snprintf(gStackTraceHelper.fPidString, kStringLength-1, "%s/etc/lldb-backtrace.sh", gSystem->Getenv("ROOTSYS")) >= kStringLength) { #else if(snprintf(gStackTraceHelper.fPidString, kStringLength-1, "%s/etc/gdb-backtrace.sh", gSystem->Getenv("ROOTSYS")) >= kStringLength) { +#endif SignalSafeErrWrite("Unable to pre-allocate executable information"); return; } diff --git a/etc/lldb-backtrace.sh b/etc/lldb-backtrace.sh new file mode 100755 index 0000000000000..7cf01f12e0d35 --- /dev/null +++ b/etc/lldb-backtrace.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# This script is used by TUnixSystem::StackTrace() on MacOS X if lldb is supported. + +tempname=`basename $0 .sh` + +OUTFILE=/dev/stdout + +if [ `uname -s` != "Darwin" ]; then + + echo "lldb stacktrace is only supported on MacOSX." + exit 1 + +else + + if test $# -lt 1; then + echo "Usage: ${tempname} [gdb-mess-file]" 1>&2 + exit 1 + fi + + TMPFILE=`mktemp -q /tmp/${tempname}.XXXXXX` + if test $? -ne 0; then + echo "${tempname}: can't create temp file, exiting..." 1>&2 + exit 1 + fi + + backtrace="thread apply all bt" + + echo $backtrace > $TMPFILE + + LLDB=${LLDB:-lldb} + + # Run LLDB, strip out unwanted noise. + $LLDB -b -x -s $TMPFILE -p $1 2>&1 < /dev/null | + sed -n \ + -e '/[Tt]hread #[0-9]/p' \ + -e '/[Ff]rame #[0-9]/p' > $OUTFILE + + rm -f $TMPFILE + +fi From 8c1bb9a542178698d43b4100a9e0c0dbde7f040d Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Thu, 5 Apr 2018 23:25:42 -0500 Subject: [PATCH 5/6] MacOSX has to explicitly initialize static struct, otherwise the pipe file descriptors becomes -1 at some point in the program. --- core/unix/src/TUnixSignalManager.cxx | 30 ++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/core/unix/src/TUnixSignalManager.cxx b/core/unix/src/TUnixSignalManager.cxx index 82057469af1f8..7eafbf1b09062 100644 --- a/core/unix/src/TUnixSignalManager.cxx +++ b/core/unix/src/TUnixSignalManager.cxx @@ -97,6 +97,17 @@ class TFdSet; +static const int kStringLength = 255; + +struct StackTraceHelper_t { + char fShellExec[kStringLength]; + char fPidString[kStringLength]; + char fPidNum[kStringLength]; + int fParentToChild[2]; + int fChildToParent[2]; + std::unique_ptr fHelperThread; +}; + #if defined(HAVE_DLADDR) && !defined(R__MACOSX) //////////////////////////////////////////////////////////////////////////////// @@ -222,23 +233,7 @@ static int SignalSafeErrWrite(const char *text) { //---- helper ----------------------------------------------------------------- -static const int kStringLength = 255; - -static struct StackTraceHelper_t { - char fShellExec[kStringLength]; - char fPidString[kStringLength]; - char fPidNum[kStringLength]; - int fParentToChild[2]; - int fChildToParent[2]; - std::unique_ptr fHelperThread; -} gStackTraceHelper = { // the order of the signals should be identical - { }, - { }, - { }, - {-1,-1}, - {-1,-1}, - nullptr -}; +static StackTraceHelper_t gStackTraceHelper; static char * const kStackArgv[] = {gStackTraceHelper.fShellExec, gStackTraceHelper.fPidString, gStackTraceHelper.fPidNum, nullptr}; @@ -277,6 +272,7 @@ void TUnixSignalManager::Init() gStackTraceHelper.fParentToChild[1] = -1; gStackTraceHelper.fChildToParent[0] = -1; gStackTraceHelper.fChildToParent[1] = -1; + gStackTraceHelper.fHelperThread = nullptr; //--- install default handlers UnixSignal(kSigChild, SigHandler); From 433a27c83d65ade0575ffc7c6f9d26a3f83c4b97 Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Fri, 6 Apr 2018 00:11:16 -0500 Subject: [PATCH 6/6] Use lldb thread command --- etc/lldb-backtrace.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/lldb-backtrace.sh b/etc/lldb-backtrace.sh index 7cf01f12e0d35..c4a60c50f9b3a 100755 --- a/etc/lldb-backtrace.sh +++ b/etc/lldb-backtrace.sh @@ -14,7 +14,7 @@ if [ `uname -s` != "Darwin" ]; then else if test $# -lt 1; then - echo "Usage: ${tempname} [gdb-mess-file]" 1>&2 + echo "Usage: ${tempname} " 1>&2 exit 1 fi @@ -24,7 +24,7 @@ else exit 1 fi - backtrace="thread apply all bt" + backtrace="thread backtrace all" echo $backtrace > $TMPFILE