Commit | Line | Data |
---|---|---|
ec064713 | 1 | #!/bin/sh |
eb6adb25 | 2 | |
4a7c7161 PMF |
3 | # usttrace by Pierre-Marc Fournier 2009 |
4 | # Distributed under the GPLv2. | |
5 | ||
ec064713 | 6 | error() { |
a4e9613d | 7 | echo "$0: error: $1" 1>&2 |
63f16f2e PMF |
8 | } |
9 | ||
ec064713 | 10 | sighandler() { |
87d40fcf | 11 | echo "Caught Ctrl-C" |
37b70e91 | 12 | if [ -z "${UST_CONSUMERD_PID}" ]; then |
ec064713 | 13 | UST_CONSUMERD_PID=`cat $pidfilepath` |
87d40fcf PMF |
14 | fi |
15 | # Tell the daemon to die | |
a1bece55 | 16 | kill -TERM "${UST_CONSUMERD_PID}" |
87d40fcf | 17 | |
9dc7b7ff | 18 | echo "Waiting for ust-consumerd to shutdown..." |
37b70e91 | 19 | wait "${UST_CONSUMERD_PID}" |
87d40fcf PMF |
20 | |
21 | rm "$pidfilepath" | |
22 | ||
23 | exit 0; | |
24 | } | |
25 | ||
cd814711 | 26 | USTTRACE_DIR="$(dirname $0)" |
9dc7b7ff | 27 | if [ -x "${USTTRACE_DIR}/ust-consumerd/ust-consumerd" ] ; then |
6b22d5c1 | 28 | # Use the not installed libraries instead |
9dc7b7ff | 29 | UST_CONSUMERD="${USTTRACE_DIR}/ust-consumerd/ust-consumerd" |
e8300fb7 | 30 | LIBINTERFORK_PATH="${USTTRACE_DIR}/libustfork/.libs/libustfork.so" |
d169a27d | 31 | LIBMALLOCWRAP_PATH="${USTTRACE_DIR}/libustinstr-malloc/.libs/libustinstr-malloc.so" |
6b22d5c1 JB |
32 | LIBUST_PATH="${USTTRACE_DIR}/libust/.libs/libust.so" |
33 | else | |
34 | # Use the libraries that the dynamic link finds | |
9dc7b7ff NC |
35 | UST_CONSUMERD="ust-consumerd" |
36 | if [ ! -x "$(which ust-consumerd 2>/dev/null)" ]; then | |
37 | error "cannot find an executable ust-consumerd; make sure its location is in the PATH" | |
63f16f2e PMF |
38 | exit 1 |
39 | fi | |
e8300fb7 | 40 | LIBINTERFORK_PATH="libustfork.so" |
d169a27d | 41 | LIBMALLOCWRAP_PATH="libustinstr-malloc.so" |
9ccc0699 | 42 | LIBUST_PATH="libust.so.0" |
6b22d5c1 | 43 | fi |
eb6adb25 | 44 | |
cd814711 | 45 | BASE_TRACE_DIR="${HOME}/.usttraces" |
eb6adb25 | 46 | |
ec064713 | 47 | usage() { |
a4e9613d JW |
48 | echo "usage: $0 OPTIONS COMMAND" 1>&2 |
49 | echo "" 1>&2 | |
50 | echo "Options:" 1>&2 | |
51 | echo " -l Runtime link with UST library." 1>&2 | |
52 | echo " (Needed only if program was not linked at compile time with libust.)" 1>&2 | |
53 | echo " -L Add path to ust libraries to LD_LIBRARY_PATH." 1>&2 | |
54 | echo " -m Instrument malloc calls." 1>&2 | |
55 | echo " -f Also trace forked processes." 1>&2 | |
56 | echo " -s Use system-wide daemon instead of creating one for this session." 1>&2 | |
57 | echo " -S Specify the subbuffer size." 1>&2 | |
58 | echo " -N Specify the number of subbuffers." 1>&2 | |
59 | echo " -o Output directory of the trace." 1>&2 | |
eb6adb25 PMF |
60 | } |
61 | ||
d1fa5f35 | 62 | while getopts ":hlLmfsWS:N:o:" options; do |
b13ba584 PMF |
63 | case $options in |
64 | l) arg_preload_libust=1;; | |
65 | L) arg_ld_std_ust=1;; | |
66 | m) arg_preload_malloc=1;; | |
67 | f) arg_preload_fork=1;; | |
89a10f62 | 68 | s) arg_syswide_daemon=1;; |
c1a44c29 | 69 | W) where=1;; |
223f2e7c AH |
70 | S) export UST_SUBBUF_SIZE=$OPTARG;; |
71 | N) export UST_SUBBUF_NUM=$OPTARG;; | |
d1fa5f35 | 72 | o) OUTPUT_DIR=$OPTARG;; |
b13ba584 PMF |
73 | h) usage; |
74 | exit 0;; | |
2a3fba49 | 75 | \?) usage |
b13ba584 | 76 | exit 1;; |
2a3fba49 | 77 | *) usage |
b13ba584 PMF |
78 | exit 1;; |
79 | esac | |
80 | done | |
81 | shift $(($OPTIND - 1)) | |
82 | ||
c1a44c29 PMF |
83 | if [ -n "$where" ]; then |
84 | echo $BASE_TRACE_DIR/$(ls "$BASE_TRACE_DIR" | tail -n 1) | |
85 | exit 0 | |
86 | fi | |
87 | ||
eb6adb25 PMF |
88 | # Validate input |
89 | if [ -z "$HOME" ]; | |
90 | then | |
91 | error "no home specified" | |
92 | fi | |
93 | ||
f3c6d904 | 94 | if [ -z "$*" ]; |
eb6adb25 PMF |
95 | then |
96 | error "no command specified" | |
97 | usage; | |
98 | exit 1 | |
99 | fi | |
100 | ||
101 | # Create directory for trace output | |
d1fa5f35 DG |
102 | if [ -n "$OUTPUT_DIR" ]; then |
103 | OUTDIR=$OUTPUT_DIR | |
104 | else | |
105 | DATESTRING="$(hostname)-$(date +%Y%m%d%H%M%S%N)" | |
106 | OUTDIR="$BASE_TRACE_DIR/$DATESTRING" | |
107 | fi | |
108 | ||
109 | # Check if directory exist | |
110 | if [ ! -d "$OUTDIR" ]; then | |
111 | mkdir -p $OUTDIR | |
112 | if [ $? -eq 1 ]; then | |
113 | exit 1 | |
114 | fi | |
115 | fi | |
eb6adb25 | 116 | |
9dc7b7ff | 117 | # Choose ust-consumerd socket path |
37b70e91 | 118 | UST_CONSUMERD_SOCKPATH="/tmp/ust-consumerd-sock-$$" |
eb6adb25 | 119 | |
89a10f62 PMF |
120 | if [ "$arg_syswide_daemon" != "1" ]; |
121 | then | |
9dc7b7ff | 122 | pidfilepath="/tmp/usttrace-$USER-$(date +%Y%m%d%H%M%S%N)-ust-consumerd-pid" |
96b73010 | 123 | trap "sighandler $pidfilepath" INT |
8232f1db | 124 | mkfifo -m 0600 "$pidfilepath" |
89a10f62 | 125 | # Start daemon |
37b70e91 | 126 | ${UST_CONSUMERD} --pidfile "$pidfilepath" -s "${UST_CONSUMERD_SOCKPATH}" -o "$OUTDIR" >"$OUTDIR/ust-consumerd.log" 2>&1 & |
9dc7b7ff NC |
127 | # ust-consumerd sets up its server socket |
128 | # ust-consumerd opens the pidfile, blocks because no one has opened it | |
0f3af9f0 PMF |
129 | # we open pidfile |
130 | # we block reading pidfile | |
9dc7b7ff NC |
131 | # ust-consumerd writes to pidfile |
132 | # ust-consumerd closes pidfile | |
0f3af9f0 | 133 | # we unblock reading pidfile |
ec064713 | 134 | UST_CONSUMERD_PID=`cat $pidfilepath` |
37b70e91 | 135 | export UST_DAEMON_SOCKET="${UST_CONSUMERD_SOCKPATH}" |
89a10f62 PMF |
136 | fi |
137 | ||
eb6adb25 | 138 | # Establish the environment for the command |
6b22d5c1 JB |
139 | ( |
140 | export UST_TRACE=1 | |
141 | export UST_AUTOPROBE=1 | |
142 | ||
143 | if [ "$arg_preload_libust" = "1" ]; | |
144 | then | |
cdf50e9e MD |
145 | if [ -n "${LIBUST_PATH%libust.so}" ]; |
146 | then | |
147 | if [ -n "$LD_LIBRARY_PATH" ]; | |
148 | then | |
149 | export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LIBUST_PATH%libust.so}" | |
150 | else | |
151 | export LD_LIBRARY_PATH="${LIBUST_PATH%libust.so}" | |
152 | fi | |
153 | fi | |
154 | if [ -n "$LIBUST_PATH" ]; | |
155 | then | |
156 | if [ -n "$LD_PRELOAD" ]; | |
157 | then | |
158 | export LD_PRELOAD="$LD_PRELOAD:$LIBUST_PATH" | |
159 | else | |
160 | export LD_PRELOAD="$LIBUST_PATH" | |
161 | fi | |
6b22d5c1 | 162 | fi |
6b22d5c1 JB |
163 | fi |
164 | ||
cdf50e9e | 165 | if [ "$arg_ld_std_ust" = "1" ] && [ -n "${LIBUST_PATH%libust.so}" ]; |
6b22d5c1 | 166 | then |
cdf50e9e MD |
167 | if [ -n "$LD_LIBRARY_PATH" ]; |
168 | then | |
169 | export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LIBUST_PATH%libust.so}" | |
170 | else | |
171 | export LD_LIBRARY_PATH="${LIBUST_PATH%libust.so}" | |
6b22d5c1 JB |
172 | fi |
173 | fi | |
174 | ||
cdf50e9e | 175 | if [ "$arg_preload_malloc" = "1" ] && [ -n "$LIBMALLOCWRAP_PATH" ]; |
6b22d5c1 | 176 | then |
cdf50e9e MD |
177 | if [ -n "$LD_PRELOAD" ]; |
178 | then | |
179 | export LD_PRELOAD="$LD_PRELOAD:$LIBMALLOCWRAP_PATH" | |
180 | else | |
181 | export LD_PRELOAD="$LIBMALLOCWRAP_PATH" | |
182 | fi | |
6b22d5c1 JB |
183 | fi |
184 | ||
cdf50e9e | 185 | if [ "$arg_preload_fork" = "1" ] && [ -n "$LIBINTERFORK_PATH" ]; |
6b22d5c1 | 186 | then |
cdf50e9e MD |
187 | if [ -n "$LD_PRELOAD" ]; |
188 | then | |
189 | export LD_PRELOAD="$LD_PRELOAD:$LIBINTERFORK_PATH" | |
190 | else | |
191 | export LD_PRELOAD="$LIBINTERFORK_PATH" | |
192 | fi | |
6b22d5c1 | 193 | fi |
b13ba584 | 194 | |
eb6adb25 | 195 | # Execute the command |
f3c6d904 | 196 | "$@" 2>&1 |
6b22d5c1 | 197 | ) | tee "$OUTDIR/app.log" |
eb6adb25 PMF |
198 | |
199 | ## Because of the keepalive mechanism, we're sure that by the time | |
200 | ## we get here, the daemon is connected to all the buffers that still exist. | |
201 | ## Therefore we can politely ask it to die when it's done. | |
202 | ||
89a10f62 PMF |
203 | if [ "$arg_syswide_daemon" != "1" ]; |
204 | then | |
205 | # Tell the daemon to die | |
a1bece55 | 206 | kill -TERM "${UST_CONSUMERD_PID}" |
89a10f62 | 207 | |
9dc7b7ff | 208 | echo "Waiting for ust-consumerd to shutdown..." |
37b70e91 | 209 | wait "${UST_CONSUMERD_PID}" |
b924c127 PMF |
210 | |
211 | rm "$pidfilepath" | |
89a10f62 | 212 | fi |
eb6adb25 | 213 | |
89a10f62 | 214 | echo "Trace was output in: " $OUTDIR |