Commit | Line | Data |
---|---|---|
eb6adb25 PMF |
1 | #!/bin/bash |
2 | ||
4a7c7161 PMF |
3 | # usttrace by Pierre-Marc Fournier 2009 |
4 | # Distributed under the GPLv2. | |
5 | ||
cd814711 PMF |
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" | |
b13ba584 | 10 | |
cd814711 | 11 | STD_LDLIBRARY_UST="${USTTRACE_DIR}/libust/.libs" |
eb6adb25 | 12 | |
cd814711 | 13 | BASE_TRACE_DIR="${HOME}/.usttraces" |
eb6adb25 PMF |
14 | |
15 | function usage () { | |
b13ba584 PMF |
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 | |
89a10f62 | 24 | echo " -s Use system-wide daemon instead of creating one for this session." 2>/dev/stderr |
eb6adb25 PMF |
25 | } |
26 | ||
27 | function error() { | |
28 | echo "$0: error: $1" 2>/dev/stderr | |
29 | } | |
30 | ||
89a10f62 | 31 | while getopts ":hlLmfs" options; do |
b13ba584 PMF |
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;; | |
89a10f62 | 37 | s) arg_syswide_daemon=1;; |
b13ba584 PMF |
38 | h) usage; |
39 | exit 0;; | |
2a3fba49 | 40 | \?) usage |
b13ba584 | 41 | exit 1;; |
2a3fba49 | 42 | *) usage |
b13ba584 PMF |
43 | exit 1;; |
44 | esac | |
45 | done | |
46 | shift $(($OPTIND - 1)) | |
47 | ||
cd814711 PMF |
48 | if [ ! -x "$USTD" ]; |
49 | then | |
50 | error "specified path to ustd not executable ($USTD)" | |
51 | exit 1 | |
52 | fi | |
53 | ||
eb6adb25 PMF |
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 | ||
89a10f62 PMF |
78 | if [ "$arg_syswide_daemon" != "1" ]; |
79 | then | |
b924c127 PMF |
80 | pidfilepath="/tmp/usttrace-$USER-$(date +%Y%m%d%H%M%S%N)-ustd-pid" |
81 | ||
89a10f62 | 82 | # Start daemon |
b924c127 PMF |
83 | $USTD -d --pidfile "$pidfilepath" -s "$SOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 & |
84 | USTDPID="$(<$pidfilepath)" | |
89a10f62 PMF |
85 | export UST_DAEMON_SOCKET="$SOCKPATH" |
86 | fi | |
87 | ||
eb6adb25 PMF |
88 | # Establish the environment for the command |
89 | export UST_TRACE=1 | |
90 | export UST_AUTOPROBE=1 | |
eb6adb25 | 91 | |
b13ba584 PMF |
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 | ||
89a10f62 PMF |
98 | if [ "$arg_ld_std_ust" = "1" ]; |
99 | then | |
100 | export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$STD_LDLIBRARY_UST" | |
101 | fi | |
102 | ||
b13ba584 PMF |
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 | |
89a10f62 | 110 | export LD_PRELOAD="$LD_PRELOAD:$LIBINTERFORK_PATH" |
b13ba584 PMF |
111 | fi |
112 | ||
89a10f62 PMF |
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. | |
b13ba584 | 118 | |
eb6adb25 | 119 | # Execute the command |
89a10f62 | 120 | bash -c "$CMD" 2>&1 | tee "$OUTDIR/app.log" |
eb6adb25 PMF |
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 | ||
89a10f62 PMF |
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" | |
b924c127 PMF |
133 | |
134 | rm "$pidfilepath" | |
89a10f62 | 135 | fi |
eb6adb25 | 136 | |
89a10f62 | 137 | echo "Trace was output in: " $OUTDIR |