public class MyClass {
public static void a(String s) {
b(s);
}
public static void b(String s) {
System.out.println(s);
}
public static void main(String[] args) {
a("Hello")
}
}
I would like my instrumented program to output :
[+] Thread X : Entering MyClass.main([])
[+] Thread X : Entering MyClass.a(java.lang.String Hello)
[+] Thread X : Entering MyClass.b(java.lang.String Hello)
[+] Thread X : Entering java.io.PrintStream.println(java.lang.String Hello)
Hello
[-] Thread X : Leaving java.io.PrintStream.println(java.lang.String Hello)
[-] Thread X : Leaving MyClass.b(java.lang.String Hello)
[-] Thread X : Leaving MyClass.a(java.lang.String Hello)
[-] Thread X : Leaving MyClass.main([])
I cannot modify the original program, that is why I am creating an agent. I think the Advice API is the way to go, as it allows me to append code at the beginning and the end of each and every function with a very low computation overhead, but I'm running into two issues :
Currently, I have the following agent :
public static void agentmain(String agentArgs, Instrumentation inst) {
AgentBuilder mybuilder = new AgentBuilder.Default()
.disableClassFormatChanges()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE);
mybuilder.type(nameMatches(".*"))
.transform((builder, type, classLoader, module) -> {
try {
return builder
.visit(Advice.to(TraceAdvice.class).on(isMethod()));
} catch (SecurityException e) {
e.printStackTrace();
return null;
}
}).installOn(inst);
}
and my TraceAdvice class implements onEnter and onExit respectively with System.out.println("Entering")
and System.out.println("Exiting")
.
Thank you in advance
Have you tried adding parameters like these to your before/after advice methods?
@Origin Method method,
@AllArguments(readOnly = false, typing = DYNAMIC) Object[] args
Printing the Method
object already gives to the method signature in one easy step. You can also print Object[] args
in any way you see fit, e.g. Arrays.toString(args)
or even Arrays.deepToString(args)
.
I simply copied the snippet from one of my advices. If you do not wish to change any argument values, of course you do not need readOnly = false
.