]> sourceware.org Git - systemtap.git/blob - java/stapbm.in
84588bab1dce13aff0f5283efff424c7bd129655
[systemtap.git] / java / stapbm.in
1 #!/bin/bash
2
3 # $1 - install/uninstall
4 # $2 - PID/unique name
5 # $3 - RULE name
6 # $4 - class
7 # $5 - method
8 # $6 - number of args
9 # $7 - entry/exit/line
10 # $8 - backtrace trigger
11
12 exec 1>&2 # redirect byteman/etc. tracing output to stderr, for easier filtering
13
14 if [[ $# -gt 8 || $# -lt 7 ]]; then
15 echo "need seven or eight arguments"
16 exit 1
17 fi
18
19 arg_command=$1
20 # resolve the overloaded parameter; PR21020
21 if [ $arg_command = "install31" ]; then
22 mode=install
23 stap="31"
24 elif [ $arg_command = "uninstall31" ]; then
25 mode=uninstall
26 stap="31"
27 elif [ $arg_command = "install" ]; then
28 mode=install
29 stap=""
30 elif [ $arg_command = "uninstall" ]; then
31 mode=uninstall
32 else
33 exit 1
34 fi
35 arg_jvmpid=$2
36 arg_rulename=$3
37 arg_class=$4
38 arg_method=$5
39 arg_argcount=$6
40 arg_probetype=$7
41
42 if [ $# -eq 7 ]; then
43 arg_backtrace=0
44 else
45 arg_backtrace=$8
46 fi
47
48 SYSTEMTAP_DIR=${SYSTEMTAP_DIR-$HOME/.systemtap}
49 BYTEMAN_HOME=${BYTEMAN_HOME-/usr/share/java/byteman}
50 JAVA_HOME=${JAVA_HOME-/usr/lib/jvm/java}
51 BYTEMAN_INSTALL_OPTS=${BYTEMAN_INSTALL_OPTS--Dorg.jboss.byteman.transform.all=true}
52 SYSTEMTAP_VERBOSE=${SYSTEMTAP_VERBOSE-0}
53
54 if [ "$SYSTEMTAP_VERBOSE" != "0" ]; then
55 BYTEMAN_INSTALL_OPTS="$BYTEMAN_INSTALL_OPTS -Dorg.jboss.byteman.verbose"
56 set -x
57 else
58 exec >/dev/null
59 # NB: preserve stderr
60 fi
61
62 prefix=@prefix@
63 exec_prefix=@exec_prefix@
64 pkglibexecdir=@pkglibexecdir@
65
66 HELPERSDT_JAR=${pkglibexecdir}/HelperSDT.jar
67 if [ ! -f ${HELPERSDT_JAR} ]; then
68 exec 1>&2
69 echo "Missing $HELPERSDT_JAR"
70 exit 1
71 fi
72
73 flagdir="$SYSTEMTAP_DIR/java"
74 mkdir -p $flagdir
75
76 # Find our target jvm pid. Due to the possibility of our
77 # target jvm pid being passed as a string, we need to allow
78 # for the possiblity that more than one pid may match the
79 # target jvm pid. If this is the case, we need to have a
80 # nested call to stapbm with the actual pid of the jvm pid
81
82 if ! [[ $arg_jvmpid =~ ^[0-9]+$ ]]; then
83 target_pid=`jps -l | grep $arg_jvmpid | cut -f1 -d" "`
84 for target in $target_pid; do
85 $0 "$arg_command" "$target" "$arg_rulename" "$arg_class" "$arg_method" "$arg_argcount" "$arg_probetype" "$arg_backtrace"
86 done
87 exit 0
88 else
89 target_pid=$arg_jvmpid
90 fi
91
92 # Our target jvm may not have the byteman agent installed yet. Let's do
93 # that first. We use a signal file in $flagdir to show that the
94 # JVM is ready for further bytemanning without a prior setup step,
95 # and include in it the designated byteman agent listening-port number.
96 #
97 byteman_installed_portfile=$flagdir/`hostname`-${target_pid}-bm
98
99 exec 200>>$byteman_installed_portfile # open/create lock file
100 flock -x 200 # exclusive-lock it
101
102 if [ -s $byteman_installed_portfile ]; then
103 bmport=`cat $byteman_installed_portfile`
104
105 if [ "$SYSTEMTAP_VERBOSE" != "0" ]; then
106 echo "Byteman agent reused for java pid $target_pid, port $bmport"
107 fi
108
109 # XXX: liveness-check the port; bmsubmit with no argument just lists current rules
110 # if fails, delete the _portfile and retry everything
111 else
112 # bmport=9091
113 bmport=`expr 9090 + $RANDOM % 10000`
114 existing=`ss -atn | awk '{print $4}' | grep ':'$bmport'$'`
115 if [ "x$existing" != "x" ]; then
116 echo "Byteman port $bmport already in use, retrying."
117 exec "$@"
118 fi
119
120 # There are two ways to invoke and run byteman operations with the jvm's we're interested
121 # in, we can alter the startup arguments to include a -javaagent parameter, or use
122 # byteman and its use of VMAttach libraries, for our case it always makes sense to use
123 # byteman classes directly and avoid -javaagent
124
125 bminstall -b -p $bmport $BYTEMAN_INSTALL_OPTS $target_pid
126 if [ $? -ne 0 ]; then
127 echo "Byteman agent failed to install for java pid $target_pid, port $bmport"
128 exit 1
129 fi
130 bmsubmit -p $bmport -s $HELPERSDT_JAR
131 if [ $? -ne 0 ]; then
132 echo "Byteman agent failed to load HelperSDT.jar java pid $target_pid, port $bmport"
133 exit 1
134 fi
135
136 echo $bmport > $byteman_installed_portfile
137
138 if [ "$SYSTEMTAP_VERBOSE" != "0" ]; then
139 echo "Byteman agent installed for java pid $target_pid, port $bmport"
140 fi
141 # XXX: Erase file to keep it from sticking around indefinitely,
142 # in case process ends, machine reboots, pid gets reused
143 # XXX: consider explicit notification to stapbm via process("java").begin/end ?
144 # ... or else: liveness-check below
145 fi
146 exec 200>&- # close file & release flock
147
148
149 function echo_bytemanrule()
150 {
151 echo "RULE $arg_rulename"
152 echo "CLASS $arg_class"
153 echo "METHOD $arg_method"
154 echo "HELPER org.systemtap.byteman.helper.HelperSDT"
155 case "$arg_probetype" in
156 entry)
157 echo "AT ENTRY"
158 ;;
159 exi*)
160 echo "AT RETURN"
161 ;;
162 *)
163 echo "AT LINE $arg_probetype"
164 ;;
165 esac
166 echo "IF TRUE"
167 if [ "$arg_backtrace" == "1" ]; then
168 echo 'DO STAP_BACKTRACE("'$arg_rulename'");'
169 else
170 echo -n 'DO '
171 fi
172 case "$arg_argcount" in
173 # For PR21010, we invoke another java<->stap ABI
174 0) echo -n 'METHOD_STAP'$stap'_PROBE0("'$arg_rulename'")' ;;
175 1) echo -n 'METHOD_STAP'$stap'_PROBE1("'$arg_rulename'", $1)' ;;
176 2) echo -n 'METHOD_STAP'$stap'_PROBE2("'$arg_rulename'", $1, $2)' ;;
177 3) echo -n 'METHOD_STAP'$stap'_PROBE3("'$arg_rulename'", $1, $2, $3)' ;;
178 4) echo -n 'METHOD_STAP'$stap'_PROBE4("'$arg_rulename'", $1, $2, $3, $4)' ;;
179 5) echo -n 'METHOD_STAP'$stap'_PROBE5("'$arg_rulename'", $1, $2, $3, $4, $5)' ;;
180 6) echo -n 'METHOD_STAP'$stap'_PROBE6("'$arg_rulename'", $1, $2, $3, $4, $5, $6)' ;;
181 7) echo -n 'METHOD_STAP'$stap'_PROBE7("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7)' ;;
182 8) echo -n 'METHOD_STAP'$stap'_PROBE8("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8)' ;;
183 9) echo -n 'METHOD_STAP'$stap'_PROBE9("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8, $9)' ;;
184 10) echo -n 'METHOD_STAP'$stap'_PROBE10("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10)' ;;
185 *) echo 'bad arg-count'; exit 1 ;;
186 esac
187 if [ "$arg_backtrace" == "1" ]; then
188 echo ';'
189 echo 'METHOD_BT_DELETE("'$arg_rulename'")'
190 else
191 echo ''
192 fi
193 echo "ENDRULE"
194 }
195
196
197 # Generate the byteman rule file on-the-fly
198 btmfile=$flagdir/`hostname`-$$.btm
199 echo_bytemanrule > $btmfile
200 trap 'rm -f $btmfile' 0 1 2 3 4 5 9 15
201
202 if [ "$SYSTEMTAP_VERBOSE" != "0" ]; then
203 echo "Byteman rule file:"
204 cat $btmfile
205 fi
206
207 if [ $mode = "uninstall" ]; then
208 bmcmd=-u
209 else
210 bmcmd=-l
211 fi
212
213 bmsubmit -p $bmport $bmcmd $btmfile
This page took 0.053882 seconds and 6 git commands to generate.