usttrace: use ustd in daemon mode, sparing a sleep and removing a race
[lttng-ust.git] / usttrace
1 #!/bin/bash
2
3 # usttrace by Pierre-Marc Fournier 2009
4 # Distributed under the GPLv2.
5
6 USTTRACE_DIR="$(dirname $0)"
7 USTD="${USTTRACE_DIR}/ustd/ustd"
8 LIBINTERFORK_PATH="${USTTRACE_DIR}/libinterfork/.libs/libinterfork.so"
9 LIBMALLOCWRAP_PATH="${USTTRACE_DIR}/libmallocwrap/.libs/libmallocwrap.so"
10
11 STD_LDLIBRARY_UST="${USTTRACE_DIR}/libust/.libs"
12
13 BASE_TRACE_DIR="${HOME}/.usttraces"
14
15 function usage () {
16 echo "usage: $0 OPTIONS COMMAND" 2>/dev/stderr
17 echo "" 2>/dev/stderr
18 echo "Options:" 2>/dev/stderr
19 echo " -l Runtime link with UST library." 2>/dev/stderr
20 echo " (Needed only if program was not linked at compile time with libust.)" 2>/dev/stderr
21 echo " -L Add path to ust libraries to LD_LIBRARY_PATH." 2>/dev/stderr
22 echo " -m Instrument malloc calls." 2>/dev/stderr
23 echo " -f Also trace forked processes." 2>/dev/stderr
24 echo " -s Use system-wide daemon instead of creating one for this session." 2>/dev/stderr
25 }
26
27 function error() {
28 echo "$0: error: $1" 2>/dev/stderr
29 }
30
31 while getopts ":hlLmfs" options; do
32 case $options in
33 l) arg_preload_libust=1;;
34 L) arg_ld_std_ust=1;;
35 m) arg_preload_malloc=1;;
36 f) arg_preload_fork=1;;
37 s) arg_syswide_daemon=1;;
38 h) usage;
39 exit 0;;
40 \?) usage
41 exit 1;;
42 *) usage
43 exit 1;;
44 esac
45 done
46 shift $(($OPTIND - 1))
47
48 if [ ! -x "$USTD" ];
49 then
50 error "specified path to ustd not executable ($USTD)"
51 exit 1
52 fi
53
54 # Prepare vars
55 CMD=$1
56
57 # Validate input
58 if [ -z "$HOME" ];
59 then
60 error "no home specified"
61 fi
62
63 if [ -z "$CMD" ];
64 then
65 error "no command specified"
66 usage;
67 exit 1
68 fi
69
70 # Create directory for trace output
71 DATESTRING="$(hostname)-$(date +%Y%m%d%H%M%S)"
72 OUTDIR="$BASE_TRACE_DIR/$DATESTRING"
73 mkdir -p "$OUTDIR"
74
75 # Choose socket path
76 SOCKPATH="/tmp/ust-sock-$$"
77
78 if [ "$arg_syswide_daemon" != "1" ];
79 then
80 pidfilepath="/tmp/usttrace-$USER-$(date +%Y%m%d%H%M%S%N)-ustd-pid"
81
82 # Start daemon
83 $USTD -d --pidfile "$pidfilepath" -s "$SOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 &
84 USTDPID="$(<$pidfilepath)"
85 export UST_DAEMON_SOCKET="$SOCKPATH"
86 fi
87
88 # Establish the environment for the command
89 export UST_TRACE=1
90 export UST_AUTOPROBE=1
91
92 if [ "$arg_preload_libust" = "1" ];
93 then
94 export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:./libust/.libs"
95 export LD_PRELOAD="$LD_PRELOAD:./libust/.libs/libust.so"
96 fi
97
98 if [ "$arg_ld_std_ust" = "1" ];
99 then
100 export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$STD_LDLIBRARY_UST"
101 fi
102
103 if [ "$arg_preload_malloc" = "1" ];
104 then
105 export LD_PRELOAD="$LD_PRELOAD:./libmallocwrap/.libs/libmallocwrap.so"
106 fi
107
108 if [ "$arg_preload_fork" = "1" ];
109 then
110 export LD_PRELOAD="$LD_PRELOAD:$LIBINTERFORK_PATH"
111 fi
112
113 # Install a handler for SIGIO. This is the signal that will be sent by ustd to
114 # the traced program to trigger the creation of its listener thread. However,
115 # it is possible that the SIGIO will be sent after the shell fork, but before
116 # the exec of the command. If this handler isn't there, bash might terminate
117 # because of a unhandled signal.
118
119 # Execute the command
120 bash -c "$CMD" 2>&1 | tee "$OUTDIR/app.log"
121
122 ## Because of the keepalive mechanism, we're sure that by the time
123 ## we get here, the daemon is connected to all the buffers that still exist.
124 ## Therefore we can politely ask it to die when it's done.
125
126 if [ "$arg_syswide_daemon" != "1" ];
127 then
128 # Tell the daemon to die
129 kill -SIGTERM "$USTDPID"
130
131 echo "Waiting for ustd to shutdown..."
132 wait "$USTDPID"
133
134 rm "$pidfilepath"
135 fi
136
137 echo "Trace was output in: " $OUTDIR
This page took 0.042796 seconds and 4 git commands to generate.