X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=usttrace;h=dc159f2cdff33897876b9b793bc9474ccc6c5ab7;hb=e7cc3e3415e0092809627e89168e1cba8b5800f6;hp=385abc643a00e06f56d1f17975c331239a9f879a;hpb=eb6adb25b8492bcfd0e72153708166563a109015;p=ust.git diff --git a/usttrace b/usttrace index 385abc6..dc159f2 100755 --- a/usttrace +++ b/usttrace @@ -1,20 +1,90 @@ #!/bin/bash -USTD="./ustd/ustd" -LIBINTERFORK="./libinterfork/.libs/libinterfork.so" +# usttrace by Pierre-Marc Fournier 2009 +# Distributed under the GPLv2. -BASE_TRACE_DIR="$HOME/.usttraces" +function error() { + echo "$0: error: $1" 2>/dev/stderr +} -function usage () { - echo "usage: $0 COMMAND" 2>/dev/stderr +function sighandler() { + echo "Caught Ctrl-C" + if [ -z "$USTDPID" ]; then + USTDPID="$(<$pidfilepath)" + fi + # Tell the daemon to die + kill -SIGTERM "$USTDPID" + + echo "Waiting for ustd to shutdown..." + wait "$USTDPID" + + rm "$pidfilepath" + + exit 0; } -function error() { - echo "$0: error: $1" 2>/dev/stderr +USTTRACE_DIR="$(dirname $0)" +if [ -x "${USTTRACE_DIR}/ustd/ustd" ] ; then + # Use the not installed libraries instead + USTD="${USTTRACE_DIR}/ustd/ustd" + LIBINTERFORK_PATH="${USTTRACE_DIR}/libustfork/.libs/libustfork.so" + LIBMALLOCWRAP_PATH="${USTTRACE_DIR}/libustinstr-malloc/.libs/libustinstr-malloc.so" + LIBUST_PATH="${USTTRACE_DIR}/libust/.libs/libust.so" +else + # Use the libraries that the dynamic link finds + USTD="ustd" + if [ ! -x "$(which ustd 2>/dev/null)" ]; then + error "cannot find an executable ustd; make sure its location is in the PATH" + exit 1 + fi + LIBINTERFORK_PATH="libustfork.so" + LIBMALLOCWRAP_PATH="libustinstr-malloc.so" + LIBUST_PATH="libust.so.0" +fi + +BASE_TRACE_DIR="${HOME}/.usttraces" + +function usage () { + echo "usage: $0 OPTIONS COMMAND" 2>/dev/stderr + echo "" 2>/dev/stderr + echo "Options:" 2>/dev/stderr + echo " -l Runtime link with UST library." 2>/dev/stderr + echo " (Needed only if program was not linked at compile time with libust.)" 2>/dev/stderr + echo " -L Add path to ust libraries to LD_LIBRARY_PATH." 2>/dev/stderr + echo " -m Instrument malloc calls." 2>/dev/stderr + echo " -f Also trace forked processes." 2>/dev/stderr + echo " -s Use system-wide daemon instead of creating one for this session." 2>/dev/stderr + echo " -S Specify the subbuffer size." 2>/dev/stderr + echo " -N Specify the number of subbuffers." 2>/dev/stderr } +while getopts ":hlLmfsWS:N:" options; do + case $options in + l) arg_preload_libust=1;; + L) arg_ld_std_ust=1;; + m) arg_preload_malloc=1;; + f) arg_preload_fork=1;; + s) arg_syswide_daemon=1;; + W) where=1;; + S) export UST_SUBBUF_SIZE=$OPTARG;; + N) export UST_SUBBUF_NUM=$OPTARG;; + h) usage; + exit 0;; + \?) usage + exit 1;; + *) usage + exit 1;; + esac +done +shift $(($OPTIND - 1)) + +if [ -n "$where" ]; then + echo $BASE_TRACE_DIR/$(ls "$BASE_TRACE_DIR" | tail -n 1) + exit 0 +fi + # Prepare vars -CMD=$1 +CMD=$* # Validate input if [ -z "$HOME" ]; @@ -30,31 +100,78 @@ then fi # Create directory for trace output -DATESTRING="$(hostname)-$(date +%Y%m%d%H%M%S)" +DATESTRING="$(hostname)-$(date +%Y%m%d%H%M%S%N)" OUTDIR="$BASE_TRACE_DIR/$DATESTRING" mkdir -p "$OUTDIR" -# Choose socket path -SOCKPATH="/tmp/ust-sock-$$" +# Choose ustd socket path +USTDSOCKPATH="/tmp/ustd-sock-$$" -# Start daemon -$USTD -s "$SOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 & -USTDPID=$! +if [ "$arg_syswide_daemon" != "1" ]; +then + pidfilepath="/tmp/usttrace-$USER-$(date +%Y%m%d%H%M%S%N)-ustd-pid" + trap "sighandler $pidfilepath" SIGINT + mkfifo -m 0600 "$pidfilepath" + # Start daemon + $USTD --pidfile "$pidfilepath" -s "$USTDSOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 & + # ustd sets up its server socket + # ustd opens the pidfile, blocks because no one has opened it + # we open pidfile + # we block reading pidfile + # ustd writes to pidfile + # ustd closes pidfile + # we unblock reading pidfile + USTDPID="$(<$pidfilepath)" + export UST_DAEMON_SOCKET="$USTDSOCKPATH" +fi # Establish the environment for the command -export UST_TRACE=1 -export UST_AUTOPROBE=1 -export UST_DAEMON_SOCKET="$SOCKPATH" +( + export UST_TRACE=1 + export UST_AUTOPROBE=1 + + if [ "$arg_preload_libust" = "1" ]; + then + if [ -n "${LIBUST_PATH%libust.so}" ] ; then + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LIBUST_PATH%libust.so}" + fi + export LD_PRELOAD="$LD_PRELOAD:$LIBUST_PATH" + fi + + if [ "$arg_ld_std_ust" = "1" ]; + then + if [ -n "$${LIBUST_PATH%libust.so}" ] ; then + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LIBUST_PATH%libust.so}" + fi + fi + + if [ "$arg_preload_malloc" = "1" ]; + then + export LD_PRELOAD="$LD_PRELOAD:$LIBMALLOCWRAP_PATH" + fi + + if [ "$arg_preload_fork" = "1" ]; + then + export LD_PRELOAD="$LD_PRELOAD:$LIBINTERFORK_PATH" + fi # Execute the command -bash -c "$CMD" + $CMD 2>&1 +) | tee "$OUTDIR/app.log" ## Because of the keepalive mechanism, we're sure that by the time ## we get here, the daemon is connected to all the buffers that still exist. ## Therefore we can politely ask it to die when it's done. -kill -SIGTERM "$USTDPID" +if [ "$arg_syswide_daemon" != "1" ]; +then + # Tell the daemon to die + kill -SIGTERM "$USTDPID" + + echo "Waiting for ustd to shutdown..." + wait "$USTDPID" + + rm "$pidfilepath" +fi -# Tell the daemon to die -echo "Waiting for ustd to shutdown..." -wait "$USTDPID" +echo "Trace was output in: " $OUTDIR