I want to redefine the bytecode of the StackOverflowError
constructor so I have a "hook" for when a stack overflow occurs. All I want to do is insert a single method call to a static method of my choosing at the start of the constructor. Is it possible to do this?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
There are several things to consider.
java.lang.StackOverflowError
. I tried it successfully on1.7.0_40
.isModifiableClass(java.lang.StackOverflowError.class)
returntrue
and I successfully redefined it inserting a method invocation into all of its constructorsClassLoader
relationships. SinceStackOverflowError
is loaded by the bootstrap loader it can only invoke methods of classes loaded by the bootstrap loader. You would have to add the target method’s class(es) to the bootstrap loaderthrow
s aStackOverflowError
manually. However, when a real stackoverflow occurs, the last thing the JVM will do is to invoke additional methods (keep in mind what the error says, the stack is full). Consequently it creates an instance ofStackOverflowError
without calling its constructor (a JVM can do that). So your instrumentation is pointless in this situation.1.7.0_40
supports the redefinition ofStackOverflowError
does not imply that other versions or other JVMs do as well.You should be able to do it using one of two ways (unless something changed in the last 1-2 years, in which case I'd love some links to changelogs/docs):
Mentioned in a comment, not very feasible I guess, modify the classes you are interested in, put them in a jar and then use the
-bootclasspath
option to load them instead of the default ones. As was mentioned before this can have some legal issues (and is a pain to do in general).You should be able to (or at least you used to be able to) instrument almost all core classes (iirc
Class
was the only exception I've seen). One of many problems you might have is the fact that many of core classes are being initialized before the agents you provide (or well theirpremain
methods to be exact) are consulted. To overcome this you will have to addCan-Retransform-Classes
property to your agent jar and then re-transform the classes you are interested in. Be aware that re-transformation is a bit less powerful and doesn't give you all the options you'd have normally with instrumentation, you can read more about it in the doc.I am assuming you know how to do instrumentation?
You can't redefine anything in java.*, or you'll get a SecurityException. You can get around this to some extent by modifying the environment (security policy and custom runtime classes), but I'd advise against messing with it.
That being said, how do you suppose your method can be called if the stack has already been overflowed/trashed? You're going to have to use some JNI voodoo to get what you want. Also, why does simply catching it not do it for you? What exactly are you trying to "get" from the exception that you can't get after it's thrown/propagated?