On Mon, 1 Sep 2025 05:11:32 GMT, David Holmes <dhol...@openjdk.org> wrote:
>> There is might be exception if current method has been called after >> exception has been thrown. It is quite rare case, but I've seem when add >> `assert(!exception_exit, "")`. It might happens if exception thrown and >> there were other upcals in the same thread before exception has been >> caught. I think I've seen it during classloading or some method >> bootstrapping. >> >> The test `TestMethodExitWithPendingException` simulates the same issue by >> calling method in the MethodExit event call back. >> For method `upCall` the `exception_exit` would be true, because the method >> is called while exception is pending. However, the method `upCall` exits >> normally and is not unwinded. So this method `post_method_exit` is called. >> >> Here is the example of such stack in the on of the tests were assertion has >> been hit. The VM tries to load classes when exception is throwing. >> >> V [libjvm.so+0x1415d6c] JvmtiExport::post_method_exit(JavaThread*, >> Method*, frame)+0x29c (jvmtiExport.cpp:1847) >> V [libjvm.so+0x1066b86] >> InterpreterRuntime::post_method_exit(JavaThread*)+0xe6 >> (interpreterRuntime.cpp:1278) >> j java.lang.Object.<init>()V+0 java.base@26-internal >> j java.lang.Throwable.<init>(Ljava/lang/String;)V+1 java.base@26-internal >> j java.lang.Error.<init>(Ljava/lang/String;)V+2 java.base@26-internal >> j java.lang.LinkageError.<init>(Ljava/lang/String;)V+2 java.base@26-internal >> j java.lang.NoClassDefFoundError.<init>(Ljava/lang/String;)V+2 >> java.base@26-internal >> v ~StubRoutines::Stub Generator call_stub_stub 0x00007f81b7c876fd >> V [libjvm.so+0x1089117] JavaCalls::call_helper(JavaValue*, methodHandle >> const&, JavaCallArguments*, JavaThread*)+0x4f7 (javaCalls.cpp:415) >> V [libjvm.so+0x108ab3f] JavaCalls::call_special(JavaValue*, Klass*, >> Symbol*, Symbol*, JavaCallArguments*, JavaThread*)+0x18f (javaCalls.cpp:323) >> V [libjvm.so+0x108b3c6] JavaCalls::construct_new_instance(InstanceKlass*, >> Symbol*, JavaCallArguments*, JavaThread*)+0x116 (javaCalls.cpp:289) >> V [libjvm.so+0xd74f4b] Exceptions::new_exception(JavaThread*, Symbol*, >> Symbol*, JavaCallArguments*, Handle)+0x1db (exceptions.cpp:320) >> V [libjvm.so+0xd7517f] Exceptions::new_exception(JavaThread*, Symbol*, >> Symbol*, JavaCallArguments*, Handle, Handle)+0x2f (exceptions.cpp:341) >> V [libjvm.so+0xd7609f] Exceptions::new_exception(JavaThread*, Symbol*, >> char const*, Handle, Handle, Exceptions::ExceptionMsgToUtf8Mode)+0x3bf >> (exceptions.cpp:424) >> V [libjvm.so+0xd7b9a0] Exceptions::_throw_msg_cause(Jav... > > Sorry I still can't see this. Method A throws an exception. The callback for > the method-exit event for method A then invokes Java method B. Method B also > has a callback enabled and so we are processing the method-exit for B. Method > B has completed normally, but the exception from method A is still listed as > pending? I can't see how that would come about as we must (temporarily) clear > the pending exception to do the upcall else the upcall method would > immediately throw that pending exception. But if we have cleared it then the > upcall method's method-exit event shouldn't be able to see it. Similarly we > must save/restore the JvmtiThreadState else we would be processing the normal > exit as if it were an exception one. Or mabye I do get it. The actual pending exception (on the ThreadShadow) must be saved, cleared and later restored, else we can't execute the Java upcall. But because we have separate paths for normal and exceptional method-exit processing, maybe we don't have to save/restore the JvmtiThreadState exception fields? But in that case are those fields even useful? To be honest I can't see how the two fields interact: there is either no exception being thrown, or there is - so only one field needed. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26886#discussion_r2312908009