Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 27 additions & 22 deletions core/unix/src/TUnixSignalManager.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::thread> fHelperThread;
};

#if defined(HAVE_DLADDR) && !defined(R__MACOSX)
////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -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<std::thread> 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};

Expand Down Expand Up @@ -272,6 +267,13 @@ 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;
gStackTraceHelper.fHelperThread = nullptr;

//--- install default handlers
UnixSignal(kSigChild, SigHandler);
UnixSignal(kSigBus, SigHandler);
Expand All @@ -290,22 +292,25 @@ 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;
}
#endif

gStackTraceHelper.fParentToChild[0] = -1;
gStackTraceHelper.fParentToChild[1] = -1;
gStackTraceHelper.fChildToParent[0] = -1;
gStackTraceHelper.fChildToParent[1] = -1;

StackTraceHelperInit();
}

Expand Down
41 changes: 41 additions & 0 deletions etc/lldb-backtrace.sh
Original file line number Diff line number Diff line change
@@ -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} <process-id>" 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 backtrace all"

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