-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8361342: Shenandoah: Evacuation may assert on invalid mirror object after JDK-8340297 #26187
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
base: master
Are you sure you want to change the base?
Conversation
👋 Welcome back stuefe! A progress list of the required criteria for merging this PR into |
@tstuefe 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 24 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 |
Webrevs
|
Only looked at this briefly, but that sounds like what I did here: #21064 -- but forgot to complete it? |
Yes, it looks like it is! The sequence of events you describe seems to also match JDK-8340364, which I think we can close as duplicate, as I have not been able to convince even myself is a real bug, not just overzealous verification. So, what do you want to do? I can finish up #21064 and test it with your Metaspace assertion patches, if you want. |
Metadata* klass = obj->metadata_field(java_lang_Class::klass_offset()); | ||
// During class redefinition the old Klass gets reclaimed and the old mirror oop's Klass reference | ||
// nulled out (hence the "klass != nullptr" condition below). However, the mirror oop may have been | ||
// forwarded if we are in the mids of an evacuation. In that case, the forwardee's Klass reference |
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.
s/mids/midst
// During class redefinition the old Klass gets reclaimed and the old mirror oop's Klass reference | ||
// nulled out (hence the "klass != nullptr" condition below). However, the mirror oop may have been | ||
// forwarded if we are in the mids of an evacuation. In that case, the forwardee's Klass reference | ||
// is nulled out. The old, forwarded, still still carries the old invalid Klass pointer. It will be |
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.
s/still still/still
The explanation and the changes make sense to me. Thank you! |
…n-invalid-mirror-object-after-JDK-8340297
…n-invalid-mirror-object-after-JDK-8340297
There’s a missing “n” in the PR and JBS issue titles: -JDK-8361342: Sheandoah evacuation may assert on invalid mirror object after JDK-8340297
+JDK-8361342: Shenandoah evacuation may assert on invalid mirror object after JDK-8340297 |
Thanks, let me just finish this, I need the closure after burning time on this non-bug :-) Note that I did not fix up the use of the array mirror klass since I thought it should always be stable. We never redefine array classes. But then it does not hurt either. I am also preparing a small improvement patch for print_obj, as per our discussion in #26117 yesterday, and will put the printing of the mirror klasses there, too. |
Thanks for the review, @earthling-amzn ! |
Sure, OK. Please pick up most of the hunks from #21064, including the array mirrors then? I don't see a need to write a full paragraph of text explaining why we need to check for forwarded objects. A simple sentence is enough, and the rest can go into the bug description. |
/contributor add @shipilev |
@tstuefe |
@shipilev ok done |
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 fine to me!
Thanks Aleksey! @earthling-amzn are you happy with this version, too? |
Hi Shenandoah devs, may I please have thoughts and reviews for this fix.
This is a fix for a problem that was uncovered during my ongoing work on Metaspace use-after-free recognition (JDK-8340297). I would like to get this fix into the codebase before eventually pushing JDK-8340297, since I want the fixes to be separate from the patch that introduces stricter testing.
For details about this issue, please see the Jira description and comment. The short version is:
ShenandoaAsserts::assert_correct
complains about an invalid Klass reference when processing the old mirror oop.I thought hard about this, but I believe this is benign, since no code should be accessing the old mirror oop's Klass field, it should always resolve the forwardee first. Class redefinition itself gets the oop address to null out from an OopHandle in Klass, which should contain the forwardee's address if the mirror was forwarded, which should ensure that only the forwardee is nulled out, never the forwarded.
Therefore I just changed the assertions.
But I would like to hear other people's opinion on this.
Note why we never saw this before: Before JDK-8340297 (as in, now), the only check ShenandoaAssert makes for Klass validity is
Metaspace::contains
, which is weak. A reclaimed Klass pointer will still point to Metaspace, so ShenandoaAssert does not complain. Metadata::is_valid() is similarly weak now, since it basically just checks a byte in the object for not null; pretty much any non-null garbage will satisfy this condition.Progress
Issue
Reviewers
Contributors
<shade@openjdk.org>
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26187/head:pull/26187
$ git checkout pull/26187
Update a local copy of the PR:
$ git checkout pull/26187
$ git pull https://git.openjdk.org/jdk.git pull/26187/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 26187
View PR using the GUI difftool:
$ git pr show -t 26187
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26187.diff
Using Webrev
Link to Webrev Comment