diff options
| author | Andrew Tridgell <tridge@samba.org> | 2008-07-22 19:13:15 +1000 |
|---|---|---|
| committer | Andrew Tridgell <tridge@samba.org> | 2008-07-22 19:13:15 +1000 |
| commit | 69f5f4b96d36c75d37e580c3129b73054d495c5b (patch) | |
| tree | 03026d7ef365ac69a89a20f5278871519d209db8 /base/root/scripts | |
| parent | 98340d4fd37f525384afa4570cf360dc08996e2c (diff) | |
added segv handler setup script
Diffstat (limited to 'base/root/scripts')
| -rwxr-xr-x | base/root/scripts/setup_segv_handler.sh | 99 |
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 |
