I solved the problem of “uninstrumenting” calls to Thread.*
methods with a very high degree of code reuse: I applied the same instrumentor that changes calls to original an Object.wait
method to the wrapper method Object.wait$$$Wrapper$$$
, except this time the roles are reversed: It changes calls to the wrapper method Thread.start
into calls to the original method Thread.start$$$Old$$$
.
Now code that was previously only used for global instrumentation is also used for local instrumentation, albeit only in the case where it needs to be “globally undone”. That might make it a bit more confusing, but generally it was the right thing to do. There wasn’t any point in rewriting what’s already there.
P.S.: Maybe locally vs. globally isn’t the right terminology. Locally vs. non-locally? Ugh…