-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8309400: JDI spec needs to clarify when OpaqueFrameException and NativeMethodException are thrown #26335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back cjplummer! A progress list of the required criteria for merging this PR into |
@plummercj This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 359 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
/csr needed |
@plummercj has indicated that a compatibility and specification (CSR) request is needed for this pull request. @plummercj please create a CSR request for issue JDK-8309400 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
@plummercj The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
It looks good. |
// 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is nothing implementation-specific here.
I'd suggest to:
StackFrameImpl
->StackFrame
;MethodImpl
->Method
;- remove
validateStackFrame
at line 408 ('MethodImpl.location()' calls it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting renaming the classes? This is a pretty conventional naming when you have classes implementing a spec defined in an interface class. There are a lot more than just StackFrame and Method that are doing this.
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(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting renaming the classes?
No, I mean
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(); | |
} | |
for (int i = 0; i < 2; i++) { | |
StackFrame sf; | |
try { | |
sf = thread.frame(i); | |
} catch (IndexOutOfBoundsException e) { | |
// This should never happen, but we need to check for it. | |
break; | |
} | |
Method meth = sf.location().method(); | |
if (meth.isNative()) { | |
throw new NativeMethodException(); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I see now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've posted one concern on the spec updates. Otherwise, it looks okay to me.
I guess, a CSR will be filed for this update. I'm not sure what do you mean by CR in the description. Do I understand this right that a potential JDWP spec update we touched out of this PR will be considered separately?
* @throws OpaqueFrameException if this thread is a suspended virtual thread and the | ||
* target VM was unable to pop the frames. | ||
* @throws OpaqueFrameException if target VM is unable to pop this frame | ||
* (e.g. a virtual thread is not suspended at an event). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'm not sure the comment at line 406 is fully correct. The IncompatibleThreadStateException
will be thrown if a virtual thread is not suspended. So, the OpaqueFrameException
will be thrown only when a virtual thread is suspended but not at an event. The same concern should apply for the line 488.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are talking about the difference between "not suspended" vs "not suspended at an event". The former results in IncompatibleThreadStateException. For the latter I felt the wording implied it was suspended, but not at an event. Maybe it should just say "suspended, but not at an event"?
The JVMTI spec does not have this issue because it doesn't mention virtual threads as part of the OPAQUE_ERROR description. It instead mentions the method being native as an example of what can cause OPAQUE_ERROR. We can't do that here because a native method results in NativeMethodException, not OpaqueFrameException.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it should just say "suspended, but not at an event"?
Yes, this would make it clear.
And yes, the JVMTI vs JDI spec difference is reasonable.
I meant CSR. I'll fix that. JDWP will be updated by #26336. |
Okay, thanks. I'll wait for CSR to review it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
The CSR is now ready for review: JDK-8363896: |
Thanks for the reviews Alan, Alex, and Serguei! /integrate |
/integrate |
Going to push as commit 9041f4c.
Your commit was automatically rebased without conflicts. |
@plummercj Pushed as commit 9041f4c. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
@plummercj The command |
Fix how ThreadReference.popFrame() and ThreadReference.forceEarlyReturn deal with JDWP OPAQUE_FRAME error.
Before virtual threads, OpaqueFrameException did not exist and these API always threw NativeMethodException when JDWP OPAQUE_FRAME error was returned. For virtual threads OpaqueFrameException was added to handle the case where a virtual thread was not suspended at an event, so the JDI implementation was updated to throw OpaqueFrameException if it detected that a native method was not the cause. It turns out however that JVMTI (and therefore JDWP) can return OPAQUE_FRAME error for reasons other than a native method or the special virtual thread case, and for platform threads we were incorrectly throwing NativeMethodException in these cases. This PR fixes that. For platform threads we now only throw NativeMethodException if a native method is detected, and otherwise throw OpaqueFrameException.
The spec language is also being cleaned up to better align with JVMTI. Rather than calling out all the reasons for OpaqueFrameException, a more generic explanation is given.
This is somewhat of a preliminary PR so I can get some feedback. I still need to do a CSR and complete testing.
Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26335/head:pull/26335
$ git checkout pull/26335
Update a local copy of the PR:
$ git checkout pull/26335
$ git pull https://git.openjdk.org/jdk.git pull/26335/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 26335
View PR using the GUI difftool:
$ git pr show -t 26335
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26335.diff
Using Webrev
Link to Webrev Comment