JDK 25 |
---|
25Unresolved |
Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
When single stepping is initiated, the following code is executed in initState() in stepControl.c: /* * Try to get a notification on frame pop. If we're in an opaque frame * we won't be able to, but we can use other methods to detect that * a native frame has exited. * * TO DO: explain the need for this notification. */ error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop) (gdata->jvmti, thread, 0); if (error == JVMTI_ERROR_OPAQUE_FRAME) { step->fromNative = JNI_TRUE; error = JVMTI_ERROR_NONE; /* continue without error */ } else if (error == JVMTI_ERROR_DUPLICATE) { error = JVMTI_ERROR_NONE; /* Already being notified, continue without error */ } else if (error != JVMTI_ERROR_NONE) { return error; } It's unclear (as the comment suggests) why this NotifyFramePop is needed. When a NotifyFramePop is done, it puts the thread in interpreter only mode (_interp_only_mode). This is done mainly so jvmti can detect when popping the frame for which NotifyFramePop has been called. Once this is done, _interp_only_mode is disabled assuming there is nothing else keeping it enabled. The problem with doing NotifyFramePop on the current frame in initState() is that even after single stepping completes, we won't yet have exited the frame that NotifyFramePop was setup on. This keeps the thread in _interp_only_mode until that frame is exited. Worse case situation is you single step in the main method of the app, and the app (or at least the thread running the main method) is forever stuck in _interp_only_mode. The above NotifyFramePop should be re-evaluated to see if it is really necessary. Unfortunately there is no way to undo a NotifyFramePop, so the only way to avoid keeping the thread in _interp_only_mode is to not have called it in the first place. The following code is in handleFramePopEvent and seems to be the code that could potentially get triggered by this NotifyFramePop: /* * If we are exiting the original stepping frame, record that * fact here. Once the next step event comes in, we can safely * stop stepping there. */ if (fromDepth > afterPopDepth ) { step->frameExited = JNI_TRUE; } However, I'm not sure how this situation could ever come about since we should always complete single stepping before returning from the original stepping frame. If there had been an exception, handleExceptionCatchEvent() would have been called, and it has similar code for dealing with exiting the original stepping frame. So that leaves doing a normal return out of the frame. I think the only way you could return out of the frame without first completing the single step is if you stepped over a return statement, maybe even a line of source with other statements on the same line before the return. If so, another way to handle this would be to install a MethodExit handler to detect exiting the original single stepping frame. It could be removed as soon as you enter a method (there's already a MethodEnter handler) and then re-installed after getting the FramePop event for the called method (NotifyFramePop is done once you enter the called method when you step over a method call).
|