Hi everyone and Rafael,
I had this project idea where I want to change how Threads work.
Basically, I want to convert a multithreaded library to a single thread for the sake of having a deterministic run via just installing an agent(actually my idea is to how controlled randomization where a second run will behave exactly like the first).
This requires me to change the behavior of almost all the classes relates threads like Thread. start/currentThread/sleep , Object.notify/wait etc...
I am a little bit inspired by https://github.com/vmlens/vmlens but trying to achieve something else.
I wanted to give bytebuddy a try but I got stuck really at the beginning:
As a baby step, I am just trying to instrument `currentThread` where I want to log it and call the original `currentThread` without changing the behavior.
```
public static Thread currentThread(@Origin(cache = false) Method m) throws Exception {
log(() -> "Thread.currentThread intercepted");
try {
//new Throwable().printStackTrace(System.out);
return (Thread) m.invoke(null);
} catch(Exception e) {
log(() -> "Exception occured");
}
return null;
}
But I get into a circular loop and see stack traces like following :
java.lang.Throwable
at main.Main$ThreadMethodReplacements.currentThread(Main.java:218)
at java.lang.Thread.currentThread(Thread.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at main.Main$ThreadMethodReplacements.currentThread(Main.java:219)
at java.lang.Thread.currentThread(Thread.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at main.Main$ThreadMethodReplacements.currentThread(Main.java:219)
at java.lang.Thread.currentThread(Thread.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at main.Main$ThreadMethodReplacements.currentThread(Main.java:219)
at java.lang.Thread.currentThread(Thread.java)
at java.lang.ThreadLocal.get(ThreadLocal.java:160)
at net.bytebuddy.agent.builder.AgentBuilder$CircularityLock$Default.acquire(AgentBuilder.java:1926)
at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10228)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at sun.misc.Unsafe.defineAnonymousClass(Native Method)
at java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass(InnerClassLambdaMetafactory.java:326)
at java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:194)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:304)
at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
at main.Main$ThreadMethodReplacements.currentThread(Main.java:216)
at java.lang.Thread.currentThread(Thread.java)
at java.lang.ThreadLocal.get(ThreadLocal.java:160)
at net.bytebuddy.agent.builder.AgentBuilder$CircularityLock$Default.acquire(AgentBuilder.java:1926)
at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Collector$ForRetransformation.doApply(AgentBuilder.java:7191)
at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Collector.apply(AgentBuilder.java:7034)
at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy.apply(AgentBuilder.java:4870)
at net.bytebuddy.agent.builder.AgentBuilder$Default.doInstall(AgentBuilder.java:9507)
at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:9428)
at net.bytebuddy.agent.builder.AgentBuilder$Default$Delegator.installOn(AgentBuilder.java:11030)
at main.Main.premain(Main.java:142)
at main.Main.install(Main.java:83)
at main.Main.main(Main.java:67)
It feels like that I get into the loop because ByteBuddy itself uses Thread.currentThread().
Is there a configuration that I am missing? Is using the @Origin Method wrong for this?
Or am I trying to achieve the impossible :)?
And my code for AgentBuilder is as follows:
Map<TypeDescription, byte[]> map = new HashMap<>();
map.put(new TypeDescription.ForLoadedType(Main.class), ClassFileLocator.ForClassLoader.read(Main.class));
map.put(new TypeDescription.ForLoadedType(Main.ThreadMethodReplacements.class), ClassFileLocator.ForClassLoader.read(Main.ThreadMethodReplacements.class));
File temp = Files.createTempDirectory("tmp").toFile();
ClassInjector.UsingInstrumentation.of(temp, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, instrumentation).inject(map);
new AgentBuilder.Default()
.ignore(nameStartsWith("net.bytebuddy."))
.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.TypeStrategy.Default.REBASE)
.type(named("java.lang.Thread"))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
return builder.method(ElementMatchers.named("currentThread"))
.intercept(MethodDelgation.to(Main.ThreadMethodReplacements.class));
}
})
.with(AgentBuilder.Listener.StreamWriting.toSystemOut())
.installOn(instrumentation);
--
You received this message because you are subscribed to the Google Groups "Byte Buddy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to byte-buddy+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/byte-buddy/de7a06be-67b7-4acf-9c78-4a9cb4be1565n%40googlegroups.com.