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