Commit | Line | Data |
---|---|---|
eb6adb25 PMF |
1 | #!/bin/bash |
2 | ||
4a7c7161 PMF |
3 | # usttrace by Pierre-Marc Fournier 2009 |
4 | # Distributed under the GPLv2. | |
5 | ||
63f16f2e PMF |
6 | function error() { |
7 | echo "$0: error: $1" 2>/dev/stderr | |
8 | } | |
9 | ||
87d40fcf PMF |
10 | function sighandler() { |
11 | echo "Caught Ctrl-C" | |
12 | if [ -z "$USTDPID" ]; then | |
13 | USTDPID="$(<$pidfilepath)" | |
14 | fi | |
15 | # Tell the daemon to die | |
16 | kill -SIGTERM "$USTDPID" | |
17 | ||
18 | echo "Waiting for ustd to shutdown..." | |
19 | wait "$USTDPID" | |
20 | ||
21 | rm "$pidfilepath" | |
22 | ||
23 | exit 0; | |
24 | } | |
25 | ||
cd814711 | 26 | USTTRACE_DIR="$(dirname $0)" |
6b22d5c1 JB |
27 | if [ -x "${USTTRACE_DIR}/ustd/ustd" ] ; then |
28 | # Use the not installed libraries instead | |
29 | USTD="${USTTRACE_DIR}/ustd/ustd" | |
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 | |
35 | USTD="ustd" | |
63f16f2e PMF |
36 | if [ ! -x "$(which ustd 2>/dev/null)" ]; then |
37 | error "cannot find an executable ustd; make sure its location is in the PATH" | |
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 PMF |
46 | |
47 | function usage () { | |
b13ba584 PMF |
48 | echo "usage: $0 OPTIONS COMMAND" 2>/dev/stderr |
49 | echo "" 2>/dev/stderr | |
50 | echo "Options:" 2>/dev/stderr | |
51 | echo " -l Runtime link with UST library." 2>/dev/stderr | |
52 | echo " (Needed only if program was not linked at compile time with libust.)" 2>/dev/stderr | |
53 | echo " -L Add path to ust libraries to LD_LIBRARY_PATH." 2>/dev/stderr | |
54 | echo " -m Instrument malloc calls." 2>/dev/stderr | |
55 | echo " -f Also trace forked processes." 2>/dev/stderr | |
89a10f62 | 56 | echo " -s Use system-wide daemon instead of creating one for this session." 2>/dev/stderr |
223f2e7c AH |
57 | echo " -S Specify the subbuffer size." 2>/dev/stderr |
58 | echo " -N Specify the number of subbuffers." 2>/dev/stderr | |
eb6adb25 PMF |
59 | } |
60 | ||
223f2e7c | 61 | while getopts ":hlLmfsWS:N:" options; do |
b13ba584 PMF |
62 | case $options in |
63 | l) arg_preload_libust=1;; | |
64 | L) arg_ld_std_ust=1;; | |
65 | m) arg_preload_malloc=1;; | |
66 | f) arg_preload_fork=1;; | |
89a10f62 | 67 | s) arg_syswide_daemon=1;; |
c1a44c29 | 68 | W) where=1;; |
223f2e7c AH |
69 | S) export UST_SUBBUF_SIZE=$OPTARG;; |
70 | N) export UST_SUBBUF_NUM=$OPTARG;; | |
b13ba584 PMF |
71 | h) usage; |
72 | exit 0;; | |
2a3fba49 | 73 | \?) usage |
b13ba584 | 74 | exit 1;; |
2a3fba49 | 75 | *) usage |
b13ba584 PMF |
76 | exit 1;; |
77 | esac | |
78 | done | |
79 | shift $(($OPTIND - 1)) | |
80 | ||
c1a44c29 PMF |
81 | if [ -n "$where" ]; then |
82 | echo $BASE_TRACE_DIR/$(ls "$BASE_TRACE_DIR" | tail -n 1) | |
83 | exit 0 | |
84 | fi | |
85 | ||
eb6adb25 | 86 | # Prepare vars |
6b22d5c1 | 87 | CMD=$* |
eb6adb25 PMF |
88 | |
89 | # Validate input | |
90 | if [ -z "$HOME" ]; | |
91 | then | |
92 | error "no home specified" | |
93 | fi | |
94 | ||
95 | if [ -z "$CMD" ]; | |
96 | then | |
97 | error "no command specified" | |
98 | usage; | |
99 | exit 1 | |
100 | fi | |
101 | ||
102 | # Create directory for trace output | |
04c989a4 | 103 | DATESTRING="$(hostname)-$(date +%Y%m%d%H%M%S%N)" |
eb6adb25 PMF |
104 | OUTDIR="$BASE_TRACE_DIR/$DATESTRING" |
105 | mkdir -p "$OUTDIR" | |
106 | ||
15588720 PMF |
107 | # Choose ustd socket path |
108 | USTDSOCKPATH="/tmp/ustd-sock-$$" | |
eb6adb25 | 109 | |
89a10f62 PMF |
110 | if [ "$arg_syswide_daemon" != "1" ]; |
111 | then | |
b924c127 | 112 | pidfilepath="/tmp/usttrace-$USER-$(date +%Y%m%d%H%M%S%N)-ustd-pid" |
87d40fcf | 113 | trap "sighandler $pidfilepath" SIGINT |
8232f1db | 114 | mkfifo -m 0600 "$pidfilepath" |
89a10f62 | 115 | # Start daemon |
15588720 | 116 | $USTD --pidfile "$pidfilepath" -s "$USTDSOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 & |
0f3af9f0 PMF |
117 | # ustd sets up its server socket |
118 | # ustd opens the pidfile, blocks because no one has opened it | |
119 | # we open pidfile | |
120 | # we block reading pidfile | |
121 | # ustd writes to pidfile | |
122 | # ustd closes pidfile | |
123 | # we unblock reading pidfile | |
b924c127 | 124 | USTDPID="$(<$pidfilepath)" |
15588720 | 125 | export UST_DAEMON_SOCKET="$USTDSOCKPATH" |
89a10f62 PMF |
126 | fi |
127 | ||
eb6adb25 | 128 | # Establish the environment for the command |
6b22d5c1 JB |
129 | ( |
130 | export UST_TRACE=1 | |
131 | export UST_AUTOPROBE=1 | |
132 | ||
133 | if [ "$arg_preload_libust" = "1" ]; | |
134 | then | |
135 | if [ -n "${LIBUST_PATH%libust.so}" ] ; then | |
136 | export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LIBUST_PATH%libust.so}" | |
137 | fi | |
138 | export LD_PRELOAD="$LD_PRELOAD:$LIBUST_PATH" | |
139 | fi | |
140 | ||
141 | if [ "$arg_ld_std_ust" = "1" ]; | |
142 | then | |
143 | if [ -n "$${LIBUST_PATH%libust.so}" ] ; then | |
144 | export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LIBUST_PATH%libust.so}" | |
145 | fi | |
146 | fi | |
147 | ||
148 | if [ "$arg_preload_malloc" = "1" ]; | |
149 | then | |
150 | export LD_PRELOAD="$LD_PRELOAD:$LIBMALLOCWRAP_PATH" | |
151 | fi | |
152 | ||
153 | if [ "$arg_preload_fork" = "1" ]; | |
154 | then | |
89a10f62 | 155 | export LD_PRELOAD="$LD_PRELOAD:$LIBINTERFORK_PATH" |
6b22d5c1 | 156 | fi |
b13ba584 | 157 | |
eb6adb25 | 158 | # Execute the command |
6b22d5c1 JB |
159 | $CMD 2>&1 |
160 | ) | tee "$OUTDIR/app.log" | |
eb6adb25 PMF |
161 | |
162 | ## Because of the keepalive mechanism, we're sure that by the time | |
163 | ## we get here, the daemon is connected to all the buffers that still exist. | |
164 | ## Therefore we can politely ask it to die when it's done. | |
165 | ||
89a10f62 PMF |
166 | if [ "$arg_syswide_daemon" != "1" ]; |
167 | then | |
168 | # Tell the daemon to die | |
169 | kill -SIGTERM "$USTDPID" | |
170 | ||
171 | echo "Waiting for ustd to shutdown..." | |
524a8072 | 172 | wait "$USTDPID" |
b924c127 PMF |
173 | |
174 | rm "$pidfilepath" | |
89a10f62 | 175 | fi |
eb6adb25 | 176 | |
89a10f62 | 177 | echo "Trace was output in: " $OUTDIR |