This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Can we obtain return value of Java methods?
- From: David Smith <dsmith at redhat dot com>
- To: Tetsuo Handa <penguin-kernel at i-love dot sakura dot ne dot jp>
- Cc: systemtap at sourceware dot org
- Date: Tue, 18 Apr 2017 14:38:57 -0500
- Subject: Re: Can we obtain return value of Java methods?
- Authentication-results: sourceware.org; auth=none
- References: <201704130111.CBE00029.MFOFOQSOHFLVtJ@I-love.SAKURA.ne.jp>
Good idea. I looked into this a bit and filed the following enhancement bug:
https://sourceware.org/bugzilla/show_bug.cgi?id=21397
You should be CC'ed on the bug.
Would you have any time to implement this yourself? We'd be happy to
point you in the right direction if you have the desire to help out.
Basically tapset-method.cxx will need to be extended. The stapbm.in
file might also need to be extended.
Thanks again for the idea.
On Wed, Apr 12, 2017 at 11:11 AM, Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
> Hello.
>
> I'd like to obtain return value of Java methods, but currently $return
> variable is not usable inside java().class().method().return probes.
>
> Since byteman accepts $! as an variable for return value of Java methods,
> I guess we can implement it by mapping $return variable inside
> java().class().method().return probes into $! variable.
>
> A manually operated demonstration is shown below.
>
> Step 1: Create Class1.java like below and compile it.
>
> ---------- Class1.java ----------
> public class Class1 {
> public static int intfunc(int a)
> {
> return a + a;
> }
> public static String strfunc(String a)
> {
> return "Hello " + a;
> }
> public static Class1 objfunc(Class1 a)
> {
> return a;
> }
> public static void main(String[] args) throws Exception
> {
> while (true) {
> Thread.sleep(5000);
> intfunc(100);
> strfunc("world");
> objfunc(new Class1());
> }
> }
> }
> ---------- Class1.java ----------
>
> Step 2: Run Java probes which prints arguments.
>
> ----------------------------------------
> # SYSTEMTAP_VERBOSE=1 stap -m class1 -e 'probe java("Class1").class("Class1").method("intfunc(int)").return { println("int = " . arg1); }
> probe java("Class1").class("Class1").method("strfunc(String)").return { println("str = " . arg1); }
> probe java("Class1").class("Class1").method("objfunc(Class1)").return { println("obj = " . arg1); }' -c 'java -cp . Class1'
> ----------------------------------------
>
> Output looks like below.
>
> ----------------------------------------
> /usr/local/libexec/systemtap/stapbm: line 160: netstat: command not found
> java -classpath /usr/share/java/byteman/byteman-install.jar:/usr/share/java/byteman/byteman.jar:/usr/lib/jvm/java/lib/tools.jar:/usr/local/libexec/systemtap/HelperSDT.jar org.jboss.byteman.agent.install.Install -b -p 11161 -Dorg.jboss.byteman.transform.all=true -Dorg.jboss.byteman.verbose 35778
> byteman jar is /usr/share/java/byteman/byteman.jar
> Setting org.jboss.byteman.transform.all=true
> Setting org.jboss.byteman.verbose=
> TransformListener() : accepting requests on localhost:11161
> Byteman agent installed for java pid 35778, port 11161
> Byteman agent reused for java pid 35778, port 11161
> Byteman rule file:
> RULE class1probe_3577
> CLASS Class1
> METHOD intfunc(int)
> HELPER org.systemtap.byteman.helper.HelperSDT
> AT RETURN
> IF TRUE
> DO METHOD_STAP31_PROBE1("class1probe_3577", $1)
> ENDRULE
> java -classpath /usr/share/java/byteman/byteman-submit.jar:/usr/share/java/byteman/byteman.jar:/usr/local/libexec/systemtap/HelperSDT.jar org.jboss.byteman.agent.submit.Submit -p 11161 -l /root/.systemtap/java/localhost.localdomain-35853.btm
> Byteman rule file:
> Byteman agent reused for java pid 35778, port 11161
> RULE class1probe_3579
> CLASS Class1
> METHOD objfunc(Class1)
> HELPER org.systemtap.byteman.helper.HelperSDT
> AT RETURN
> IF TRUE
> DO METHOD_STAP31_PROBE1("class1probe_3579", $1)
> ENDRULE
> java -classpath /usr/share/java/byteman/byteman-submit.jar:/usr/share/java/byteman/byteman.jar:/usr/local/libexec/systemtap/HelperSDT.jar org.jboss.byteman.agent.submit.Submit -p 11161 -l /root/.systemtap/java/localhost.localdomain-35856.btm
> Byteman rule file:
> RULE class1probe_3578
> CLASS Class1
> METHOD strfunc(String)
> HELPER org.systemtap.byteman.helper.HelperSDT
> AT RETURN
> IF TRUE
> DO METHOD_STAP31_PROBE1("class1probe_3578", $1)
> ENDRULE
> java -classpath /usr/share/java/byteman/byteman-submit.jar:/usr/share/java/byteman/byteman.jar:/usr/local/libexec/systemtap/HelperSDT.jar org.jboss.byteman.agent.submit.Submit -p 11161 -l /root/.systemtap/java/localhost.localdomain-35877.btm
> TransformListener() : handling connection on port 11161
> retransforming Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3577 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.intfunc(int) int for rule class1probe_3577
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3577 in class Class1
> TransformListener() : handling connection on port 11161
> install rule class1probe_3577
>
> retransforming Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3577 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.intfunc(int) int for rule class1probe_3577
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3577 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3579 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.objfunc(Class1) Class1 for rule class1probe_3579
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3579 in class Class1
> TransformListener() : handling connection on port 11161
> install rule class1probe_3579
>
> retransforming Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3577 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.intfunc(int) int for rule class1probe_3577
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3577 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3579 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.objfunc(Class1) Class1 for rule class1probe_3579
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3579 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3578 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.strfunc(java.lang.String) java.lang.String for rule class1probe_3578
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3578 in class Class1
> install rule class1probe_3578
>
> Rule.execute called for class1probe_3577_3
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3577 execute()
> Rule.execute called for class1probe_3578_5
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3578 execute()
> Rule.execute called for class1probe_3579_4
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3579 execute()
> int = 100
> str = world
> obj = Class1@28cc6a8
> Rule.execute called for class1probe_3577_3
> class1probe_3577 execute()
> Rule.execute called for class1probe_3578_5
> class1probe_3578 execute()
> Rule.execute called for class1probe_3579_4
> class1probe_3579 execute()
> int = 100
> str = world
> obj = Class1@684640e6
> ----------------------------------------
>
> Step 3: Copy the contents of byteman rule files, with $1 replaced with $!
> and save the result as /tmp/class1.btm .
>
> ---------- /tmp/class1.btm ----------
> RULE class1probe_3577_2
> CLASS Class1
> METHOD intfunc(int)
> HELPER org.systemtap.byteman.helper.HelperSDT
> AT RETURN
> IF TRUE
> DO METHOD_STAP31_PROBE1("class1probe_3577", $!)
> ENDRULE
>
> RULE class1probe_3578_2
> CLASS Class1
> METHOD strfunc(String)
> HELPER org.systemtap.byteman.helper.HelperSDT
> AT RETURN
> IF TRUE
> DO METHOD_STAP31_PROBE1("class1probe_3578", $!)
> ENDRULE
>
> RULE class1probe_3579_2
> CLASS Class1
> METHOD objfunc(Class1)
> HELPER org.systemtap.byteman.helper.HelperSDT
> AT RETURN
> IF TRUE
> DO METHOD_STAP31_PROBE1("class1probe_3579", $!)
> ENDRULE
> ---------- /tmp/class1.btm ----------
>
> Step 4: Load /tmp/class1.btm into running java proess.
>
> ----------------------------------------
> java -classpath /usr/share/java/byteman/byteman-submit.jar:/usr/share/java/byteman/byteman.jar:/usr/local/libexec/systemtap/HelperSDT.jar org.jboss.byteman.agent.submit.Submit -p 11161 -l /tmp/class1.btm
> ----------------------------------------
>
> Output looks like below.
>
> ----------------------------------------
> TransformListener() : handling connection on port 11161
> retransforming Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3577 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.intfunc(int) int for rule class1probe_3577
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3577 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3579 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.objfunc(Class1) Class1 for rule class1probe_3579
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3579 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3578 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.strfunc(java.lang.String) java.lang.String for rule class1probe_3578
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3578 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3577_2 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.intfunc(int) int for rule class1probe_3577_2
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3577_2 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3578_2 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.strfunc(java.lang.String) java.lang.String for rule class1probe_3578_2
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3578_2 in class Class1
> org.jboss.byteman.agent.Transformer : possible trigger for rule class1probe_3579_2 in class Class1
> RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into Class1.objfunc(Class1) Class1 for rule class1probe_3579_2
> org.jboss.byteman.agent.Transformer : inserted trigger for class1probe_3579_2 in class Class1
> Rule.execute called for class1probe_3577_6
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3577 execute()
> Rule.execute called for class1probe_3577_2_9
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3577_2 execute()
> Rule.execute called for class1probe_3578_8
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3578 execute()
> Rule.execute called for class1probe_3578_2_10
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3578_2 execute()
> Rule.execute called for class1probe_3579_7
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3579 execute()
> Rule.execute called for class1probe_3579_2_11
> HelperManager.install for helper classorg.systemtap.byteman.helper.HelperSDT
> class1probe_3579_2 execute()
> int = 100
> int = 200
> str = world
> str = Hello world
> obj = Class1@5578cce2
> obj = Class1@5578cce2
> ^CWARNING: Child process exited with status 130
> WARNING: /usr/local/bin/staprun exited with status: 1
> Pass 5: run failed. [man error::pass5]
> ----------------------------------------
--
David Smith
Principal Software Engineer
Red Hat