summaryrefslogtreecommitdiffstats
path: root/base/root/scripts
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-07-22 19:13:15 +1000
committerAndrew Tridgell <tridge@samba.org>2008-07-22 19:13:15 +1000
commit69f5f4b96d36c75d37e580c3129b73054d495c5b (patch)
tree03026d7ef365ac69a89a20f5278871519d209db8 /base/root/scripts
parent98340d4fd37f525384afa4570cf360dc08996e2c (diff)
added segv handler setup script
Diffstat (limited to 'base/root/scripts')
-rwxr-xr-xbase/root/scripts/setup_segv_handler.sh99
1 files changed, 99 insertions, 0 deletions
diff --git a/base/root/scripts/setup_segv_handler.sh b/base/root/scripts/setup_segv_handler.sh
new file mode 100755
index 0000000..b1bfc87
--- /dev/null
+++ b/base/root/scripts/setup_segv_handler.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+# a script to setup a segmentation fault handler on a SoFS cluster
+# tridge@samba.org July 2008
+
+set -e
+
+echo "Creating source file"
+mkdir -p /usr/local/src
+
+cat <<EOFSOURCE > /usr/local/src/segv_handler.c
+#define _GNU_SOURCE
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <dlfcn.h>
+
+static int segv_handler(int sig)
+{
+ char cmd[100];
+ char progname[100];
+ char *p;
+ int n;
+
+ n = readlink("/proc/self/exe",progname,sizeof(progname));
+ progname[n] = 0;
+
+ p = strrchr(progname, '/');
+ *p = 0;
+
+ snprintf(cmd, sizeof(cmd), "/usr/local/bin/backtrace %d 2>&1 | tee /var/log/segv/segv_%s.%d.out > /dev/console",
+ (int)getpid(), p+1, (int)getpid());
+ system(cmd);
+ signal(SIGSEGV, SIG_DFL);
+ return 0;
+}
+
+static void segv_init() __attribute__((constructor));
+void segv_init(void)
+{
+ signal(SIGSEGV, (sighandler_t) segv_handler);
+ signal(SIGBUS, (sighandler_t) segv_handler);
+}
+EOFSOURCE
+
+mkdir -p /usr/local/bin
+cat <<EOFSOURCE > /usr/local/bin/backtrace
+#!/bin/sh
+
+# we want everything on stderr, so the program is not disturbed
+exec 1>&2
+
+PID=\$1
+TMPFILE=/tmp/gdb.\$\$
+cat << EOF > \$TMPFILE
+set height 0
+bt full
+thread apply all bt full
+quit
+EOF
+gdb -batch -x \$TMPFILE --pid \$PID < /dev/null
+/bin/rm -f \$TMPFILE
+
+EOFSOURCE
+
+chmod +x /usr/local/bin/backtrace
+
+mkdir -p /var/log/segv
+
+echo "Compiling 64 bit shared library"
+mkdir -p /usr/local/lib
+gcc -m64 -shared -fPIC -o /usr/local/lib/segv_handler64.so /usr/local/src/segv_handler.c
+
+echo "Compiling 32 bit shared library"
+mkdir -p /usr/local/lib
+gcc -m32 -shared -fPIC -o /usr/local/lib/segv_handler32.so /usr/local/src/segv_handler.c
+
+echo "Modifying /lib/ld-2.5.so for LD_PRELO32"
+sed -e 's@/etc/ld.so.preload@/etc/ld.so.prelo32@g' -i.orig /lib/ld-2.5.so
+
+echo "Creating /etc/ld.so.prelo32"
+echo "/usr/local/lib/segv_handler32.so" > /etc/ld.so.prelo32
+
+echo "Creating /etc/ld.so.preload"
+echo "/usr/local/lib/segv_handler64.so" >> /etc/ld.so.preload
+sort -u < /etc/ld.so.preload > /etc/ld.so.preload.$$
+mv /etc/ld.so.preload.$$ /etc/ld.so.preload
+
+echo "Copying install to other nodes"
+onnode -p all rsync $HOSTNAME:/usr/local/bin/backtrace /usr/local/bin/
+onnode -p all rsync $HOSTNAME:/usr/local/lib/segv_handler*so /usr/local/lib
+onnode -p all rsync $HOSTNAME:/etc/ld.so.preload /etc/
+onnode -p all rsync $HOSTNAME:/etc/ld.so.prelo32 /etc/
+
+cat <<EOF
+segv_handler installed. To take full effect you must restart your daemons
+or reboot
+EOF