in src/main/java/com/jetbrains/jdi/StackFrameImpl.java [516:565]
void pop() throws IncompatibleThreadStateException {
validateStackFrame();
// flush caches and disable caching until command completion
try {
PacketStream stream = thread.sendResumingCommand(
() -> JDWP.StackFrame.PopFrames.enqueueCommand(vm, thread, id));
JDWP.StackFrame.PopFrames.waitForReply(vm, stream);
} catch (JDWPException exc) {
switch (exc.errorCode()) {
case JDWP.Error.OPAQUE_FRAME:
if (thread.isVirtual()) {
// We first need to find out if the current frame is native, or if the
// previous frame is native, in which case we throw NativeMethodException
for (int i = 0; i < 2; i++) {
StackFrameImpl sf;
try {
sf = (StackFrameImpl)thread.frame(i);
} catch (IndexOutOfBoundsException e) {
// This should never happen, but we need to check for it.
break;
}
sf.validateStackFrame();
MethodImpl meth = (MethodImpl)sf.location().method();
if (meth.isNative()) {
throw new NativeMethodException();
}
}
// No native frames involved. Must have been due to thread
// not being mounted.
throw new InvalidStackFrameException("Opaque frame");
// throw new OpaqueFrameException();
} else {
throw new NativeMethodException();
}
case JDWP.Error.THREAD_NOT_SUSPENDED:
throw new IncompatibleThreadStateException(
"Thread not current or suspended");
case JDWP.Error.INVALID_THREAD: /* zombie */
throw new IncompatibleThreadStateException("zombie");
case JDWP.Error.NO_MORE_FRAMES:
throw new InvalidStackFrameException(
"No more frames on the stack");
default:
throw exc.toJDIException();
}
}
// enable caching - suspended again
vm.state().freeze();
}