Skip to content

Commit 6ded984

Browse files
committed
Add java backtrace functionality
This commit adds two functions, sprint_java_backtrace() and print_java_backtrace. The former returns the java backtrace as one string (may need to set the -DMAXSTRINGLEN var to read the entire backtrace), and latter prints the java backtrace one line at a time. *java/HelperSDT.c - Add METHOD_STAP_BT and _METHOD_BT_DELETE jni functions *java/HelperSDT.h - ditto *java/..../HelperSDT.java - ditto *java/stapbm.in - add conditional calls to functions based on backtrace flag status *tapset-method.cxx - add the probe points for METHOD_STAP_BT and METHOD_BT_DELETE to be handled *tapset/java.stp - add sprint_java_backtrace and print_java_backtrace functions
1 parent e5474ed commit 6ded984

File tree

6 files changed

+380
-43
lines changed

6 files changed

+380
-43
lines changed

java/HelperSDT.c

+26
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,29 @@ JNIEXPORT void JNICALL Java_org_systemtap_byteman_helper_HelperSDT_METHOD_1STAP_
491491
arg10.vartype.c = get_java_string(env, _arg10);
492492
STAP_PROBE11(HelperSDT, method__10, arg1.vartype.d, arg2.vartype.d, arg3.vartype.d, arg4.vartype.d, arg5.vartype.d, arg6.vartype.d, arg7.vartype.d, arg8.vartype.d, arg9.vartype.d, arg10.vartype.d, rulename);
493493
}
494+
495+
/*
496+
* Class: HelperSDT
497+
* Method: METHOD_STAP_BT
498+
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)V
499+
*/
500+
JNIEXPORT void JNICALL Java_org_systemtap_byteman_helper_HelperSDT_METHOD_1STAP_1BT
501+
(JNIEnv *env, jobject obj, jstring _rulename, jstring _exception, jint _counter)
502+
{
503+
char* rulename = get_java_string(env, _rulename);
504+
char* excp = get_java_string(env, _exception);
505+
int stdepth = _counter;
506+
STAP_PROBE3(HelperSDT, method__bt, excp, stdepth, rulename);
507+
}
508+
509+
/*
510+
* Class: HelperSDT
511+
* Method: METHOD_BT_DELETE
512+
* Signature: (Ljava/lang/String;)V
513+
*/
514+
JNIEXPORT void JNICALL Java_org_systemtap_byteman_helper_HelperSDT_METHOD_1BT_1DELETE
515+
(JNIEnv *env, jobject obj, jstring _rulename)
516+
{
517+
char* rulename = get_java_string(env, _rulename);
518+
STAP_PROBE1(HelperSDT, method__bt__delete, rulename);
519+
}

java/HelperSDT.h

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

java/org/systemtap/byteman/helper/HelperSDT.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
package org.systemtap.byteman.helper;
2+
import java.io.StringWriter;
3+
import java.io.PrintWriter;
4+
import java.lang.Throwable;
5+
26
public class HelperSDT<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
37
{
8+
public void STAP_BACKTRACE(String rulename){
9+
Throwable e = new Throwable();
10+
StringWriter sw = new StringWriter();
11+
e.printStackTrace(new PrintWriter(sw));
12+
String exceptionAsString = sw.toString();
13+
String[] stackline = exceptionAsString.split("\n");
14+
int __counter = 0;
15+
for(String result : stackline){
16+
METHOD_STAP_BT(rulename, result, __counter);
17+
__counter++;
18+
}
19+
}
420
public native void METHOD_STAP_PROBE0(String rulename);
521
public native void METHOD_STAP_PROBE1(String rulename, T2 arg1);
622
public native void METHOD_STAP_PROBE2(String rulename, T2 arg1, T3 arg2);
@@ -12,7 +28,9 @@ public class HelperSDT<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
1228
public native void METHOD_STAP_PROBE8(String rulename, T2 arg1, T3 arg2, T4 arg3, T5 arg4, T6 arg5, T7 arg6, T8 arg7, T9 arg8);
1329
public native void METHOD_STAP_PROBE9(String rulename, T2 arg1, T3 arg2, T4 arg3, T5 arg4, T6 arg5, T7 arg6, T8 arg7, T9 arg8, T10 arg9);
1430
public native void METHOD_STAP_PROBE10(String rulename, T2 arg1, T3 arg2, T4 arg3, T5 arg4, T6 arg5, T7 arg6, T8 arg7, T9 arg8, T10 arg9, T11 arg10);
15-
static{
16-
System.loadLibrary("HelperSDT_" + System.getProperty("os.arch"));
31+
public native void METHOD_STAP_BT(String rulename, String exceptionAsString, int __counter);
32+
public native void METHOD_BT_DELETE(String rulename);
33+
static{
34+
System.loadLibrary("HelperSDT_" + System.getProperty("os.arch"));
1735
}
1836
}

java/stapbm.in

+35-16
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
# $5 - method
88
# $6 - number of args
99
# $7 - entry/exit/line
10+
# $8 - backtrace trigger
1011

1112
exec 1>&2 # redirect byteman/etc. tracing output to stderr, for easier filtering
1213

13-
if [ $# -ne 7 ]; then
14-
echo "need exactly seven arguments"
14+
if [[ $# -gt 8 || $# -lt 7 ]]; then
15+
echo "need seven or eight arguments"
1516
exit 1
1617
fi
1718

@@ -23,6 +24,12 @@ arg_method=$5
2324
arg_argcount=$6
2425
arg_probetype=$7
2526

27+
if [ $# -eq 7 ]; then
28+
arg_backtrace=0
29+
else
30+
arg_backtrace=$8
31+
fi
32+
2633
SYSTEMTAP_DIR=${SYSTEMTAP_DIR-$HOME/.systemtap}
2734
BYTEMAN_HOME=${BYTEMAN_HOME-/usr/share/java/byteman}
2835
JAVA_HOME=${JAVA_HOME-/usr/lib/jvm/java}
@@ -40,7 +47,7 @@ fi
4047
# the byteman and byteman-submit jars should be in ${BYTEMAN_HOME}/lib
4148
BYTEMAN_JAR=${BYTEMAN_HOME}/byteman.jar
4249
if [ ! -r ${BYTEMAN_JAR} ]; then
43-
echo "Missing $BYTEMAN_JAR"
50+
echo "Missing $BYTEMAN_JAR"
4451
exit 1
4552
fi
4653

@@ -95,7 +102,7 @@ mkdir -p $flagdir
95102
if [[ $arg_jvmpid != *[[:digit:]]* ]]; then
96103
target_pid=`jps -l | grep $arg_jvmpid | cut -f1 -d" "`
97104
for target in $target_pid; do
98-
$0 $arg_command $target $arg_rulename $arg_class $arg_method $arg_argcount $arg_probetype
105+
$0 $arg_command $target $arg_rulename $arg_class $arg_method $arg_argcount $arg_probetype $arg_backtrace
99106
done;
100107
exit 0
101108
else
@@ -119,6 +126,7 @@ if [ -s $byteman_installed_portfile ]; then
119126
echo "Byteman agent reused for java pid $target_pid, port $bmport"
120127
fi
121128

129+
122130
# XXX: liveness-check the port; bmsubmit with no argument just lists current rules
123131
# if fails, delete the _portfile and retry everything
124132
else
@@ -132,7 +140,7 @@ else
132140

133141
# There are two ways to invoke and run byteman operations with the jvm's we're interested
134142
# in, we can alter the startup arguments to include a -javaagent parameter, or use
135-
# byteman and its use of VMAttach libraries, for our case it always makes sense to use
143+
# byteman and its use of VMAttach libraries, for our case it always makes sense to use
136144
# byteman classes directly and avoid -javaagent
137145

138146
if [ "$STAPBM_VERBOSE" != "no" ]; then
@@ -174,20 +182,31 @@ function echo_bytemanrule()
174182
;;
175183
esac
176184
echo "IF TRUE"
185+
if [ "$arg_backtrace" == "1" ]; then
186+
echo 'DO STAP_BACKTRACE("'$arg_rulename'");'
187+
else
188+
echo -n 'DO '
189+
fi
177190
case "$arg_argcount" in
178-
0) echo 'DO METHOD_STAP_PROBE0("'$arg_rulename'")' ;;
179-
1) echo 'DO METHOD_STAP_PROBE1("'$arg_rulename'", $1)' ;;
180-
2) echo 'DO METHOD_STAP_PROBE2("'$arg_rulename'", $1, $2)' ;;
181-
3) echo 'DO METHOD_STAP_PROBE3("'$arg_rulename'", $1, $2, $3)' ;;
182-
4) echo 'DO METHOD_STAP_PROBE4("'$arg_rulename'", $1, $2, $3, $4)' ;;
183-
5) echo 'DO METHOD_STAP_PROBE5("'$arg_rulename'", $1, $2, $3, $4, $5)' ;;
184-
6) echo 'DO METHOD_STAP_PROBE6("'$arg_rulename'", $1, $2, $3, $4, $5, $6)' ;;
185-
7) echo 'DO METHOD_STAP_PROBE7("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7)' ;;
186-
8) echo 'DO METHOD_STAP_PROBE8("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8)' ;;
187-
9) echo 'DO METHOD_STAP_PROBE9("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8, $9)' ;;
188-
10) echo 'DO METHOD_STAP_PROBE10("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10)' ;;
191+
0) echo -n 'METHOD_STAP_PROBE0("'$arg_rulename'")' ;;
192+
1) echo -n 'METHOD_STAP_PROBE1("'$arg_rulename'", $1)' ;;
193+
2) echo -n 'METHOD_STAP_PROBE2("'$arg_rulename'", $1, $2)' ;;
194+
3) echo -n 'METHOD_STAP_PROBE3("'$arg_rulename'", $1, $2, $3)' ;;
195+
4) echo -n 'METHOD_STAP_PROBE4("'$arg_rulename'", $1, $2, $3, $4)' ;;
196+
5) echo -n 'METHOD_STAP_PROBE5("'$arg_rulename'", $1, $2, $3, $4, $5)' ;;
197+
6) echo -n 'METHOD_STAP_PROBE6("'$arg_rulename'", $1, $2, $3, $4, $5, $6)' ;;
198+
7) echo -n 'METHOD_STAP_PROBE7("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7)' ;;
199+
8) echo -n 'METHOD_STAP_PROBE8("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8)' ;;
200+
9) echo -n 'METHOD_STAP_PROBE9("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8, $9)' ;;
201+
10) echo -n 'METHOD_STAP_PROBE10("'$arg_rulename'", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10)' ;;
189202
*) echo 'bad arg-count'; exit 1 ;;
190203
esac
204+
if [ "$arg_backtrace" == "1" ]; then
205+
echo ';'
206+
echo 'METHOD_BT_DELETE("'$arg_rulename'")'
207+
else
208+
echo ''
209+
fi
191210
echo "ENDRULE"
192211
}
193212

0 commit comments

Comments
 (0)