summaryrefslogtreecommitdiff
path: root/src/pmdas/bash/bashproc.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/bash/bashproc.sh')
-rwxr-xr-xsrc/pmdas/bash/bashproc.sh64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/pmdas/bash/bashproc.sh b/src/pmdas/bash/bashproc.sh
new file mode 100755
index 0000000..4d867a7
--- /dev/null
+++ b/src/pmdas/bash/bashproc.sh
@@ -0,0 +1,64 @@
+# Common bash(1) procedures to be used in the Performance Co-Pilot
+# Bash PMDA trace instrumentation mechanism
+#
+# Copyright (c) 2012 Nathan Scott. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+
+pcp_trace()
+{
+ command="$1"
+ shift
+
+ case "$command"
+ in
+ setup|init)
+ [ -z "${PCP_TMP_DIR}" ] && return 0 # incorrect call sequence
+ trap "pcp_trace off" 0
+ export PCP_TRACE_DIR="${PCP_TMP_DIR}/pmdabash"
+ export PCP_TRACE_HEADER="${PCP_TRACE_DIR}/.$$"
+ export PCP_TRACE_DATA="${PCP_TRACE_DIR}/$$"
+ ;;
+
+ stop|off)
+ exec 99>/dev/null
+ # unlink is performed by pmdabash to resolve race conditions
+ unset BASH_XTRACEFD PCP_TRACE_DIR PCP_TRACE_HEADER PCP_TRACE_DATA
+ ;;
+
+ start|on)
+ # series of sanity checks first
+ [ -n "${BASH_VERSION}" ] || return 0 # wrong shell
+ [ "${BASH_VERSINFO[0]}" -ge 4 ] || return 0 # no support
+ [ "${BASH_VERSINFO[0]}" -ne 4 -o "${BASH_VERSINFO[1]}" -ge 2 ] || \
+ return 0 # no support
+ [ -z "${PCP_TMP_DIR}" ] && return 0 # incorrect setup
+ [ -z "${PCP_TRACE_DIR}" ] && pcp_trace init $@ # not yet tracing
+ [ -d "${PCP_TRACE_DIR}" ] || return 0 # no pcp pmda yet
+
+ # is this the child of a traced shell?
+ [ -e /proc/self/fd/99 ] && pcp_trace init $@
+
+ trap "pcp_trace on" 13 # reset on sigpipe (consumer died)
+ printf -v PCP_START '%(%s)T' -2
+ mkfifo -m 600 "${PCP_TRACE_DATA}" 2>/dev/null || return 0
+ # header: version, command, parent, and start time
+ echo "version:1 ppid:${PPID} date:${PCP_START} + $@" \
+ > "${PCP_TRACE_HEADER}" || return 0
+ # setup link between xtrace & fifo
+ exec 99>"${PCP_TRACE_DATA}"
+ BASH_XTRACEFD=99 # magic bash environment variable
+ set -o xtrace # start tracing from here onward
+ # traces: time, line#, and (optionally) function
+ PS4='time:${SECONDS} line:${LINENO} func:${FUNCNAME[0]-} + '
+ ;;
+ esac
+}